@Override void writeValue(WriteBuffer b, Span value) {
      TRACE_ID.write(b, value.traceId());
      PARENT_ID.write(b, value.parentId());
      ID.write(b, value.id());
      KIND.write(b, toByte(value.kind()));
      NAME.write(b, value.name());
      TIMESTAMP.write(b, value.timestampAsLong());
      DURATION.write(b, value.durationAsLong());
      LOCAL_ENDPOINT.write(b, value.localEndpoint());
      REMOTE_ENDPOINT.write(b, value.remoteEndpoint());

      List<Annotation> annotations = value.annotations();
      for (Annotation annotation : annotations) {
        ANNOTATION.write(b, annotation);
      }

      Map<String, String> tags = value.tags();
      if (!tags.isEmpty()) { // avoid allocating an iterator when empty
        for (Map.Entry<String, String> entry : tags.entrySet()) {
          TAG.write(b, entry);
        }
      }

      SpanField.DEBUG.write(b, Boolean.TRUE.equals(value.debug()));
      SpanField.SHARED.write(b, Boolean.TRUE.equals(value.shared()));
    }
Contributes to a builder as opposed to reading values directly. Avoids allocation.
zipkin/src/main/java/zipkin2/internal/Proto3ZipkinFields.java