diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/loader/SmithyModelLoader.java b/smithy-model/src/main/java/software/amazon/smithy/model/loader/SmithyModelLoader.java index 6edcda6cdc6..91cc3a1dc04 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/loader/SmithyModelLoader.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/loader/SmithyModelLoader.java @@ -301,7 +301,7 @@ private static void parse(State state) { if (token.type == UNQUOTED) { parseStatement(token, state); } else if (token.type == ANNOTATION) { - state.pendingTraits.add(parseTraitValue(token, state, false)); + state.pendingTraits.add(parseTraitValue(token, state, TraitValueType.SHAPE)); } else if (token.type == CONTROL) { parseControlStatement(state, token); } else if (token.type == DOC) { @@ -386,7 +386,9 @@ private static void requireNamespaceOrThrow(State state) { } } - private static Pair parseTraitValue(Token token, State state, boolean memberScope) { + private enum TraitValueType { SHAPE, MEMBER, APPLY } + + private static Pair parseTraitValue(Token token, State state, TraitValueType type) { try { requireNamespaceOrThrow(state); @@ -394,14 +396,22 @@ private static Pair parseTraitValue(Token token, State state, bool ShapeId.fromOptionalNamespace(state.visitor.getNamespace(), token.lexeme); Pair result = Pair.of(token.lexeme, parseTraitValueBody(state)); + // `apply` doesn't require any specific token to follow. + if (type == TraitValueType.APPLY) { + return result; + } + + // Other kinds of trait values require an annotation or definition to follow. if (!state.peek().isPresent()) { throw state.syntax("Found a trait doesn't apply to anything"); } Token next = state.peek().get(); - if (next.type != ANNOTATION - && (next.type != UNQUOTED || (!memberScope && !SUPPORTS_TRAITS.contains(next.lexeme)))) { - throw state.syntax("Traits cannot be applied to `" + next.lexeme + "`"); + if (next.type != ANNOTATION) { + if (next.type != UNQUOTED + || (type != TraitValueType.MEMBER && !SUPPORTS_TRAITS.contains(next.lexeme))) { + throw state.syntax("Traits cannot be applied to `" + next.lexeme + "`"); + } } return result; @@ -572,7 +582,7 @@ private static void parseStructuredContents( Token token = state.expect(ANNOTATION, QUOTED, UNQUOTED, RBRACE, DOC); while (token.type != RBRACE) { if (token.type == ANNOTATION) { - memberTraits.add(parseTraitValue(token, state, true)); + memberTraits.add(parseTraitValue(token, state, TraitValueType.MEMBER)); // Traits can't come before a closing brace, so continue // to make sure they come before another trait or a key. } else if (token.type == DOC) { @@ -659,7 +669,7 @@ private static void parseApply(State state) { String name = state.expect(UNQUOTED).lexeme; ShapeId id = ShapeId.fromOptionalNamespace(state.visitor.getNamespace(), name); Token token = state.expect(ANNOTATION); - Pair trait = parseTraitValue(token, state, false); + Pair trait = parseTraitValue(token, state, TraitValueType.APPLY); state.visitor.onTrait(id, trait.getLeft(), trait.getRight()); state.expectNewline(); } diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/traits.json b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/traits.json index 5247cc238ba..034c7922d4b 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/traits.json +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/traits.json @@ -23,7 +23,8 @@ }, "E": { "type": "string", - "smithy.api#documentation": "Hello!" + "smithy.api#documentation": "Hello!", + "smithy.api#deprecated": {} }, "F": { "type": "string", diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/traits.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/traits.smithy index 1130b7e6435..5bc3bc589b9 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/traits.smithy +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/loader/valid/traits.smithy @@ -129,3 +129,5 @@ string T many lines.""") string U + +apply E @deprecated