diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/validation/node/IntEnumPlugin.java b/smithy-model/src/main/java/software/amazon/smithy/model/validation/node/IntEnumPlugin.java new file mode 100644 index 00000000000..e33be0e8c14 --- /dev/null +++ b/smithy-model/src/main/java/software/amazon/smithy/model/validation/node/IntEnumPlugin.java @@ -0,0 +1,32 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.model.validation.node; + +import java.util.Collection; +import software.amazon.smithy.model.node.NumberNode; +import software.amazon.smithy.model.shapes.IntEnumShape; +import software.amazon.smithy.model.validation.ValidationUtils; + + +/** + * Validates NumberNodes against intEnum shapes' allowed enum values. + */ +final class IntEnumPlugin extends FilteredPlugin { + + IntEnumPlugin() { + super(IntEnumShape.class, NumberNode.class); + } + + @Override + protected void check(IntEnumShape shape, NumberNode node, Context context, Emitter emitter) { + Collection values = shape.getEnumValues().values(); + if (!values.contains(node.getValue().intValue())) { + emitter.accept(node, String.format( + "Integer value provided for `%s` must be one of the following values: %s, but found %s", + shape.getId(), ValidationUtils.tickedList(values), node.getValue())); + } + } +} diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/validation/node/NodeValidatorPlugin.java b/smithy-model/src/main/java/software/amazon/smithy/model/validation/node/NodeValidatorPlugin.java index 5398f3529c3..2042ece5e88 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/validation/node/NodeValidatorPlugin.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/validation/node/NodeValidatorPlugin.java @@ -64,6 +64,7 @@ static List getBuiltins() { new PatternTraitPlugin(), new RangeTraitPlugin(), new StringEnumPlugin(), + new IntEnumPlugin(), new StringLengthPlugin(), new UniqueItemsPlugin()); } diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/validation/NodeValidationVisitorTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/validation/NodeValidationVisitorTest.java index 779a5f7b3c9..1712d51032d 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/validation/NodeValidationVisitorTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/validation/NodeValidationVisitorTest.java @@ -132,6 +132,13 @@ public static Collection data() { {"ns.foo#Integer", "9", new String[] {"Value provided for `ns.foo#Integer` must be greater than or equal to 10, but found 9"}}, {"ns.foo#Integer", "10.2", new String[] {"integer shapes must not have floating point values, but found `10.2` provided for `ns.foo#Integer`"}}, + // intEnum + {"ns.foo#IntEnum", "1", null}, + {"ns.foo#IntEnum", "2", null}, + {"ns.foo#IntEnum", "3", new String[] {"Integer value provided for `ns.foo#IntEnum` must be one of the following values: `1`, `2`, but found 3"}}, + {"ns.foo#IntEnum", "true", new String[] {"Expected number value for intEnum shape, `ns.foo#IntEnum`; found boolean value, `true`"}}, + {"ns.foo#IntEnum", "1.1", new String[] {"intEnum shapes must not have floating point values, but found `1.1` provided for `ns.foo#IntEnum`"}}, + // long {"ns.foo#Long", "10", null}, {"ns.foo#Long", "true", new String[] {"Expected number value for long shape, `ns.foo#Long`; found boolean value, `true`"}}, diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/validation/node-validator.json b/smithy-model/src/test/resources/software/amazon/smithy/model/validation/node-validator.json index 3b3375b42cc..f4100e4c524 100644 --- a/smithy-model/src/test/resources/software/amazon/smithy/model/validation/node-validator.json +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/validation/node-validator.json @@ -28,6 +28,23 @@ } } }, + "ns.foo#IntEnum": { + "type": "intEnum", + "members": { + "V1": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": 1 + } + }, + "V2": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": 2 + } + } + } + }, "ns.foo#Long": { "type": "long", "traits": {