public UdtValue parse()

in core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/UdtCodec.java [166:293]


  public UdtValue parse(@Nullable String value) {
    if (value == null || value.isEmpty() || value.equalsIgnoreCase("NULL")) {
      return null;
    }

    UdtValue udt = cqlType.newValue();
    int length = value.length();

    int position = ParseUtils.skipSpaces(value, 0);
    if (value.charAt(position) != '{') {
      throw new IllegalArgumentException(
          String.format(
              "Cannot parse UDT value from \"%s\" at character %d: expecting '{' but got '%c'",
              value, position, value.charAt(position)));
    }

    position++;
    position = ParseUtils.skipSpaces(value, position);

    if (position == length) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot parse UDT value from \"%s\" at character %d: expecting CQL identifier or '}', got EOF",
              value, position));
    }

    CodecRegistry registry = cqlType.getAttachmentPoint().getCodecRegistry();

    CqlIdentifier id = null;
    while (position < length) {
      if (value.charAt(position) == '}') {
        position = ParseUtils.skipSpaces(value, position + 1);
        if (position == length) {
          return udt;
        }
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", at character %d expecting EOF or blank, but got \"%s\"",
                value, position, value.substring(position)));
      }
      int n;
      try {
        n = ParseUtils.skipCQLId(value, position);
      } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", cannot parse a CQL identifier at character %d",
                value, position),
            e);
      }
      id = CqlIdentifier.fromInternal(value.substring(position, n));
      position = n;

      if (!cqlType.contains(id)) {
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", unknown CQL identifier at character %d: \"%s\"",
                value, position, id));
      }

      position = ParseUtils.skipSpaces(value, position);
      if (position == length) {
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", at field %s (character %d) expecting ':', but got EOF",
                value, id, position));
      }
      if (value.charAt(position) != ':') {
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", at field %s (character %d) expecting ':', but got '%c'",
                value, id, position, value.charAt(position)));
      }
      position++;
      position = ParseUtils.skipSpaces(value, position);

      try {
        n = ParseUtils.skipCQLValue(value, position);
      } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", invalid CQL value at field %s (character %d)",
                value, id, position),
            e);
      }

      String fieldValue = value.substring(position, n);
      // This works because ids occur at most once in UDTs
      DataType fieldType = cqlType.getFieldTypes().get(cqlType.firstIndexOf(id));
      TypeCodec<Object> codec = registry.codecFor(fieldType);
      Object parsed;
      try {
        parsed = codec.parse(fieldValue);
      } catch (Exception e) {
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", invalid CQL value at field %s (character %d): %s",
                value, id, position, e.getMessage()),
            e);
      }
      udt = udt.set(id, parsed, codec);
      position = n;

      position = ParseUtils.skipSpaces(value, position);
      if (position == length) {
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", at field %s (character %d) expecting ',' or '}', but got EOF",
                value, id, position));
      }
      if (value.charAt(position) == '}') {
        continue;
      }
      if (value.charAt(position) != ',') {
        throw new IllegalArgumentException(
            String.format(
                "Cannot parse UDT value from \"%s\", at field %s (character %d) expecting ',' but got '%c'",
                value, id, position, value.charAt(position)));
      }
      ++position; // skip ','

      position = ParseUtils.skipSpaces(value, position);
    }
    throw new IllegalArgumentException(
        String.format(
            "Cannot parse UDT value from \"%s\" at field %s (character %d): expecting CQL identifier or '}', got EOF",
            value, id, position));
  }