@Override Span readValue(ReadBuffer buffer, int length) {
      buffer.require(length); // more convenient to check up-front vs partially read
      int endPos = buffer.pos() + length;

      // now, we are in the span fields
      Span.Builder builder = Span.newBuilder();
      while (buffer.pos() < endPos) {
        int nextKey = buffer.readVarint32();
        switch (nextKey) {
          case TRACE_ID_KEY:
            builder.traceId(TRACE_ID.readLengthPrefixAndValue(buffer));
            break;
          case PARENT_ID_KEY:
            builder.parentId(PARENT_ID.readLengthPrefixAndValue(buffer));
            break;
          case ID_KEY:
            builder.id(ID.readLengthPrefixAndValue(buffer));
            break;
          case KIND_KEY:
            int kind = buffer.readVarint32();
            if (kind == 0) break;
            if (kind > Span.Kind.values().length) break;
            builder.kind(Span.Kind.values()[kind - 1]);
            break;
          case NAME_KEY:
            builder.name(NAME.readLengthPrefixAndValue(buffer));
            break;
          case TIMESTAMP_KEY:
            builder.timestamp(TIMESTAMP.readValue(buffer));
            break;
          case DURATION_KEY:
            builder.duration(buffer.readVarint64());
            break;
          case LOCAL_ENDPOINT_KEY:
            builder.localEndpoint(LOCAL_ENDPOINT.readLengthPrefixAndValue(buffer));
            break;
          case REMOTE_ENDPOINT_KEY:
            builder.remoteEndpoint(REMOTE_ENDPOINT.readLengthPrefixAndValue(buffer));
            break;
          case ANNOTATION_KEY:
            ANNOTATION.readLengthPrefixAndValue(buffer, builder);
            break;
          case TAG_KEY:
            TAG.readLengthPrefixAndValue(buffer, builder);
            break;
          case DEBUG_KEY:
            if (DEBUG.read(buffer)) builder.debug(true);
            break;
          case SHARED_KEY:
            if (SHARED.read(buffer)) builder.shared(true);
            break;
          default:
            logAndSkip(buffer, nextKey);
        }
      }
      return builder.build();
    }
Contributes to a builder as opposed to reading values directly. Avoids allocation.
zipkin/src/main/java/zipkin2/internal/Proto3ZipkinFields.java