in smithy-model/src/main/java/software/amazon/smithy/model/selector/SelectorParser.java [81:144]
private InternalSelector createSelector() {
ws();
// Require at least one selector.
switch (peek()) {
case ':': // function
skip();
return parseSelectorFunction();
case '[': // attribute
skip();
if (peek() == '@') {
skip();
return parseScopedAttribute();
} else {
return parseAttribute();
}
case '>': // forward undirected neighbor
skip();
return new ForwardNeighborSelector(ListUtils.of());
case '<': // reverse [un]directed neighbor
skip();
if (peek() == '-') { // reverse directed neighbor (<-[X, Y, Z]-)
skip();
expect('[');
return parseSelectorDirectedReverseNeighbor();
} else { // reverse undirected neighbor (<)
return new ReverseNeighborSelector(ListUtils.of());
}
case '~': // ~>
skip();
expect('>');
return new RecursiveNeighborSelector();
case '-': // forward directed neighbor
skip();
expect('[');
return parseSelectorForwardDirectedNeighbor();
case '*': // Any shape
skip();
return InternalSelector.IDENTITY;
case '$': // variable
skip();
return parseVariable();
default:
if (ParserUtils.isIdentifierStart(peek())) {
String identifier = ParserUtils.parseIdentifier(this);
switch (identifier) {
case "number":
return new ShapeTypeCategorySelector(NumberShape.class);
case "simpleType":
return new ShapeTypeCategorySelector(SimpleShape.class);
case "collection":
return new ShapeTypeCategorySelector(CollectionShape.class);
default:
ShapeType shape = ShapeType.fromString(identifier)
.orElseThrow(() -> syntax("Unknown shape type: " + identifier));
return new ShapeTypeSelector(shape);
}
} else if (peek() == Character.MIN_VALUE) {
throw syntax("Unexpected selector EOF");
} else {
throw syntax("Unexpected selector character: " + peek());
}
}
}