parseJsonPath

fun parseJsonPath(expression: String): CatalogPath

Reads an RFC 9535 query as a shape, over the sub-language this type can represent.

The inverse of toJsonPath, and the reader to reach for when the expression came from outside the engine — a command line, a configuration file, or the same string a JSONPath evaluation was handed. parse reads the engine's own spelling and accepts neither single quotes nor RFC escapes; this one accepts both, which is what lets one expression be written once and used for both a filter and an extraction.

Accepted: $, the shorthand .name and .*, and a bracketed ['name'], ["name"], [*] or [:], with blanks where §2.3.5's S allows them. Names carry §2.3.1.1's escapes, so $['a\nb'] is a, newline, b — and not what parse makes of the same eight characters, where a backslash escapes the next character literally. The two grammars are different languages that happen to share a bracket.

[*] is accepted as CatalogStep.AnyElement while toJsonPath emits [:], and the asymmetry is deliberate. The two selectors do not mean the same thing — see toJsonPath — so the lenient direction takes what a consumer will type and the strict direction emits what cannot be misread. Postel's rule, applied where the meanings differ. Do not "fix" this into a symmetry: making the reader refuse [*] would reject the spelling every existing filter uses, and making the writer emit [*] would reintroduce a rendering that is wrong over objects.

A construct this type has no step for is refused by name, never approximated. [0], .., [?…], a slice with a bound or a step, and two selectors in one segment each raise PathNotRepresentableException carrying the PathConstruct — so a caller can tell a typo the operator can fix from a question this grammar does not ask, which is the distinction an IllegalArgumentException from parse cannot make. Widening $.items[0] to $.items[*] would answer a question nobody asked.

CatalogPath.parseJsonPath("""$['response']['body']['@type']""")   // = $.response.body["@type"]
CatalogPath.parseJsonPath("$.items[*].sku") // = $.items[*].sku

Throws

if expression is a valid JSONPath query naming something this type has no step for.

with the offending position, for malformed input.