static Span parseSpan(JsonParser parser) throws IOException {
    if (!parser.isExpectedStartObjectToken()) {
      throw new IllegalArgumentException("Not a valid JSON object, start token: " +
        parser.currentToken());
    }

    Span.Builder result = Span.newBuilder();

    JsonToken value;
    while ((value = parser.nextValue()) != JsonToken.END_OBJECT) {
      if (value == null) {
        throw new IOException("End of input while parsing object.");
      }
      if (value == JsonToken.VALUE_NULL) {
        continue;
      }
      switch (parser.currentName()) {
        case "traceId":
          result.traceId(parser.getText());
          break;
        case "parentId":
          result.parentId(parser.getText());
          break;
        case "id":
          result.id(parser.getText());
          break;
        case "kind":
          result.kind(Span.Kind.valueOf(parser.getText()));
          break;
        case "name":
          result.name(parser.getText());
          break;
        case "timestamp":
          result.timestamp(parser.getLongValue());
          break;
        case "duration":
          result.duration(parser.getLongValue());
          break;
        case "localEndpoint":
          result.localEndpoint(parseEndpoint(parser));
          break;
        case "remoteEndpoint":
          result.remoteEndpoint(parseEndpoint(parser));
          break;
        case "annotations":
          if (value != JsonToken.START_ARRAY) {
            throw new IOException("Invalid span, expecting annotations array start, got: " +
              value);
          }
          while (parser.nextToken() != JsonToken.END_ARRAY) {
            Annotation a = parseAnnotation(parser);
            result.addAnnotation(a.timestamp(), a.value());
          }
          break;
        case "tags":
          if (value != JsonToken.START_OBJECT) {
            throw new IOException("Invalid span, expecting tags object, got: " + value);
          }
          while (parser.nextValue() != JsonToken.END_OBJECT) {
            result.putTag(parser.currentName(), parser.getValueAsString());
          }
          break;
        case "debug":
          result.debug(parser.getBooleanValue());
          break;
        case "shared":
          result.shared(parser.getBooleanValue());
          break;
        default:
          // Skip
      }
    }

    return result.build();
  }
JSON serialization utilities and parsing code.
zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java