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));
}