diff --git a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/HttpChecksumTraitValidator.java b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/HttpChecksumTraitValidator.java index 06613737195..69507d6520e 100644 --- a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/HttpChecksumTraitValidator.java +++ b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/HttpChecksumTraitValidator.java @@ -260,8 +260,8 @@ private List validateResponseChecksumConfiguration( }); // Check for header binding conflicts with each error shape. - if (!operation.getErrors().isEmpty()) { - for (ShapeId id : operation.getErrors()) { + if (!operation.getErrorsSet().isEmpty()) { + for (ShapeId id : operation.getErrorsSet()) { StructureShape shape = model.expectShape(id, StructureShape.class); events.addAll(validateHeaderConflicts(operation, shape)); } diff --git a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/clientendpointdiscovery/ClientEndpointDiscoveryValidator.java b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/clientendpointdiscovery/ClientEndpointDiscoveryValidator.java index 50782646a53..92e049e2404 100644 --- a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/clientendpointdiscovery/ClientEndpointDiscoveryValidator.java +++ b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/clientendpointdiscovery/ClientEndpointDiscoveryValidator.java @@ -138,7 +138,7 @@ private List validateOperation(OperationShape operation, List discoveryInfo.getOptionalError().isPresent()) - .filter(discoveryInfo -> !operation.getErrors() + .filter(discoveryInfo -> !operation.getErrorsSet() .contains( discoveryInfo.getOptionalError().get().getId())) .map(discoveryInfo -> error(operation, diff --git a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/protocols/ProtocolHttpPayloadValidator.java b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/protocols/ProtocolHttpPayloadValidator.java index f524c6adf03..b9d4fdb48a8 100644 --- a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/protocols/ProtocolHttpPayloadValidator.java +++ b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/protocols/ProtocolHttpPayloadValidator.java @@ -76,7 +76,7 @@ private List validateService( List responseBindings = bindingIndex.getResponseBindings(operation, Location.PAYLOAD); validateBindings(model, responseBindings).ifPresent(events::add); - for (ShapeId error : operation.getErrors()) { + for (ShapeId error : operation.getErrorsSet()) { List errorBindings = bindingIndex.getResponseBindings(error, Location.PAYLOAD); validateBindings(model, errorBindings).ifPresent(events::add); } diff --git a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/protocols/QueryErrorCodeValidator.java b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/protocols/QueryErrorCodeValidator.java index 5db5d8902d3..0a04326bd24 100644 --- a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/protocols/QueryErrorCodeValidator.java +++ b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/protocols/QueryErrorCodeValidator.java @@ -48,9 +48,9 @@ public List validate(Model model) { private List validateService(Model model, ServiceShape service) { TopDownIndex index = TopDownIndex.of(model); - Set errors = new HashSet<>(service.getErrors()); + Set errors = new HashSet<>(service.getErrorsSet()); for (OperationShape operation : index.getContainedOperations(service)) { - errors.addAll(operation.getErrors()); + errors.addAll(operation.getErrorsSet()); } Map> errorCodeBindings = new HashMap<>(); diff --git a/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/AddedOperationError.java b/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/AddedOperationError.java index f6091312e1f..b87a1604cfa 100644 --- a/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/AddedOperationError.java +++ b/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/AddedOperationError.java @@ -29,14 +29,14 @@ public List evaluate(Differences differences) { } private List createErrorViolations(ChangedShape change, Model newModel) { - if (change.getOldShape().getErrors().equals(change.getNewShape().getErrors())) { + if (change.getOldShape().getErrorsSet().equals(change.getNewShape().getErrorsSet())) { return Collections.emptyList(); } List events = new ArrayList<>(); - for (ShapeId error : change.getNewShape().getErrors()) { + for (ShapeId error : change.getNewShape().getErrorsSet()) { SourceLocation errorSource = newModel.expectShape(error).getSourceLocation(); - if (!change.getOldShape().getErrors().contains(error)) { + if (!change.getOldShape().getErrorsSet().contains(error)) { events.add( ValidationEvent.builder() .id(getEventId() + "." + error.getName()) diff --git a/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/AddedServiceError.java b/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/AddedServiceError.java index 09d755339ea..ff3def2c993 100644 --- a/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/AddedServiceError.java +++ b/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/AddedServiceError.java @@ -26,13 +26,13 @@ public List evaluate(Differences differences) { } private List createErrorViolations(ChangedShape change) { - if (change.getOldShape().getErrors().equals(change.getNewShape().getErrors())) { + if (change.getOldShape().getErrorsSet().equals(change.getNewShape().getErrorsSet())) { return Collections.emptyList(); } List events = new ArrayList<>(); - for (ShapeId id : change.getNewShape().getErrors()) { - if (!change.getOldShape().getErrors().contains(id)) { + for (ShapeId id : change.getNewShape().getErrorsSet()) { + if (!change.getOldShape().getErrorsSet().contains(id)) { events.add(warning(change.getNewShape(), String.format( "The `%s` error was added to the `%s` service, making this error common " diff --git a/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/RemovedOperationError.java b/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/RemovedOperationError.java index a7e14a1a8b3..ea14cb7c925 100644 --- a/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/RemovedOperationError.java +++ b/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/RemovedOperationError.java @@ -27,13 +27,13 @@ public List evaluate(Differences differences) { } private List createErrorViolations(ChangedShape change) { - if (change.getOldShape().getErrors().equals(change.getNewShape().getErrors())) { + if (change.getOldShape().getErrorsSet().equals(change.getNewShape().getErrorsSet())) { return Collections.emptyList(); } List events = new ArrayList<>(); - for (ShapeId error : change.getOldShape().getErrors()) { - if (!change.getNewShape().getErrors().contains(error)) { + for (ShapeId error : change.getOldShape().getErrorsSet()) { + if (!change.getNewShape().getErrorsSet().contains(error)) { events.add( ValidationEvent.builder() .id(getEventId() + "." + error.getName()) diff --git a/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/RemovedServiceError.java b/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/RemovedServiceError.java index 3406e8764cf..ff4519accc5 100644 --- a/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/RemovedServiceError.java +++ b/smithy-diff/src/main/java/software/amazon/smithy/diff/evaluators/RemovedServiceError.java @@ -26,13 +26,13 @@ public List evaluate(Differences differences) { } private List createErrorViolations(ChangedShape change) { - if (change.getOldShape().getErrors().equals(change.getNewShape().getErrors())) { + if (change.getOldShape().getErrorsSet().equals(change.getNewShape().getErrorsSet())) { return Collections.emptyList(); } List events = new ArrayList<>(); - for (ShapeId id : change.getOldShape().getErrors()) { - if (!change.getNewShape().getErrors().contains(id)) { + for (ShapeId id : change.getOldShape().getErrorsSet()) { + if (!change.getNewShape().getErrorsSet().contains(id)) { events.add(warning(change.getNewShape(), String.format( "The `%s` error was removed from the `%s` service. This means that it " diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/OperationIndex.java b/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/OperationIndex.java index 84be7027627..d1019163e71 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/OperationIndex.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/OperationIndex.java @@ -5,6 +5,7 @@ package software.amazon.smithy.model.knowledge; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -55,15 +56,15 @@ public OperationIndex(Model model) { outputs.put(operation.getId(), shape); boundOutputOperations.computeIfAbsent(shape.getId(), id -> new HashSet<>()).add(operation); }); - addErrorsFromShape(model, operation.getId(), operation.getErrors()); + addErrorsFromShape(model, operation.getId(), operation.getErrorsSet()); } for (ServiceShape service : model.getServiceShapes()) { - addErrorsFromShape(model, service.getId(), service.getErrors()); + addErrorsFromShape(model, service.getId(), service.getErrorsSet()); } } - private void addErrorsFromShape(Model model, ShapeId source, List errorShapeIds) { + private void addErrorsFromShape(Model model, ShapeId source, Collection errorShapeIds) { List errorShapes = new ArrayList<>(errorShapeIds.size()); Shape sourceShape = model.expectShape(source); for (ShapeId target : errorShapeIds) { diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/neighbor/NeighborVisitor.java b/smithy-model/src/main/java/software/amazon/smithy/model/neighbor/NeighborVisitor.java index 6e7f52b69a7..ed625c91af0 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/neighbor/NeighborVisitor.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/neighbor/NeighborVisitor.java @@ -68,7 +68,7 @@ private List initializeRelationships(Shape shape, int knownMemberC @Override public List serviceShape(ServiceShape shape) { - int neededSize = shape.getOperations().size() + shape.getResources().size() + shape.getErrors().size(); + int neededSize = shape.getOperations().size() + shape.getResources().size() + shape.getErrorsSet().size(); List result = initializeRelationships(shape, neededSize); for (ShapeId operation : shape.getOperations()) { @@ -79,7 +79,7 @@ public List serviceShape(ServiceShape shape) { push(result, shape, RelationshipType.RESOURCE, resource); } - for (ShapeId errorId : shape.getErrors()) { + for (ShapeId errorId : shape.getErrorsSet()) { push(result, shape, RelationshipType.ERROR, errorId); } @@ -120,7 +120,7 @@ public List operationShape(OperationShape shape) { ShapeId output = shape.getOutput().orElse(null); // Calculate the number of relationships up front. - int assumedRelationshipCount = shape.getErrors().size() + int assumedRelationshipCount = shape.getErrorsSet().size() + (input == null ? 0 : 1) + (output == null ? 0 : 1); List result = initializeRelationships(shape, assumedRelationshipCount); @@ -133,7 +133,7 @@ public List operationShape(OperationShape shape) { push(result, shape, RelationshipType.OUTPUT, output); } - for (ShapeId errorId : shape.getErrors()) { + for (ShapeId errorId : shape.getErrorsSet()) { push(result, shape, RelationshipType.ERROR, errorId); } diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ModelSerializer.java b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ModelSerializer.java index 233fe6b4763..74f0ef47c4d 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ModelSerializer.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ModelSerializer.java @@ -346,7 +346,7 @@ public Node operationShape(OperationShape shape) { createTypedBuilder(shape) .withMember("input", serializeReference(shape.getInputShape())) .withMember("output", serializeReference(shape.getOutputShape())) - .withOptionalMember("errors", createOptionalIdList(shape.getIntroducedErrors()))) + .withOptionalMember("errors", createOptionalIdList(shape.getIntroducedErrorsSet()))) .build(); } @@ -394,7 +394,7 @@ public Node serviceShape(ServiceShape shape) { serviceBuilder.withOptionalMember("operations", createOptionalIdList(shape.getIntroducedOperations())); serviceBuilder.withOptionalMember("resources", createOptionalIdList(shape.getIntroducedResources())); - serviceBuilder.withOptionalMember("errors", createOptionalIdList(shape.getIntroducedErrors())); + serviceBuilder.withOptionalMember("errors", createOptionalIdList(shape.getIntroducedErrorsSet())); if (!shape.getIntroducedRename().isEmpty()) { ObjectNode.Builder renameBuilder = Node.objectNodeBuilder(); diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/OperationShape.java b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/OperationShape.java index fc77680c039..31b7e24f49f 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/OperationShape.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/OperationShape.java @@ -17,6 +17,7 @@ import software.amazon.smithy.model.traits.MixinTrait; import software.amazon.smithy.model.traits.UnitTypeTrait; import software.amazon.smithy.utils.BuilderRef; +import software.amazon.smithy.utils.ListUtils; import software.amazon.smithy.utils.ToSmithyBuilder; /** @@ -25,8 +26,8 @@ public final class OperationShape extends Shape implements ToSmithyBuilder { private final ShapeId input; private final ShapeId output; - private final List errors; - private final List introducedErrors; + private final Set errors; + private final Set introducedErrors; private OperationShape(Builder builder) { super(builder, false); @@ -43,11 +44,11 @@ private OperationShape(Builder builder) { // here. Set computedErrors = new LinkedHashSet<>(); for (Shape shape : builder.getMixins().values()) { - shape.asOperationShape().ifPresent(mixin -> computedErrors.addAll(mixin.getErrors())); + shape.asOperationShape().ifPresent(mixin -> computedErrors.addAll(mixin.getErrorsSet())); } introducedErrors = builder.errors.copy(); computedErrors.addAll(introducedErrors); - errors = Collections.unmodifiableList(new ArrayList<>(computedErrors)); + errors = Collections.unmodifiableSet(new LinkedHashSet<>(computedErrors)); } if (hasTrait(MixinTrait.ID) && (!input.equals(UnitTypeTrait.UNIT) || !output.equals(UnitTypeTrait.UNIT))) { @@ -68,7 +69,7 @@ public Builder toBuilder() { return updateBuilder(builder()) .input(input) .output(output) - .errors(getIntroducedErrors()); + .errors(getIntroducedErrorsSet()); } @Override @@ -134,8 +135,13 @@ public ShapeId getOutputShape() { return output; } + @Deprecated + public List getErrors() { + return ListUtils.copyOf(errors); + } + /** - *

Gets a list of the error shape IDs bound directly to the operation + *

Gets a set of the error shape IDs bound directly to the operation * that can be encountered. * *

This DOES NOT include errors that are common to a service. Operations @@ -152,17 +158,22 @@ public ShapeId getOutputShape() { * @see #getErrors(ServiceShape) * @see OperationIndex#getErrors(ToShapeId, ToShapeId) */ - public List getErrors() { + public Set getErrorsSet() { return errors; } + @Deprecated + public List getIntroducedErrors() { + return ListUtils.copyOf(introducedErrors); + } + /** * Gets the errors introduced by the shape and not inherited * from mixins. * * @return Returns the introduced errors. */ - public List getIntroducedErrors() { + public Set getIntroducedErrorsSet() { return introducedErrors; } @@ -177,8 +188,8 @@ public List getIntroducedErrors() { * @see OperationIndex#getErrors(ToShapeId, ToShapeId) */ public List getErrors(ServiceShape service) { - Set result = new LinkedHashSet<>(service.getErrors()); - result.addAll(getErrors()); + Set result = new LinkedHashSet<>(service.getErrorsSet()); + result.addAll(getErrorsSet()); return new ArrayList<>(result); } @@ -200,7 +211,7 @@ public boolean equals(Object other) { public static final class Builder extends AbstractShapeBuilder { private ShapeId input = UnitTypeTrait.UNIT; private ShapeId output = UnitTypeTrait.UNIT; - private final BuilderRef> errors = BuilderRef.forList(); + private final BuilderRef> errors = BuilderRef.forOrderedSet(); @Override public ShapeType getShapeType() { @@ -307,7 +318,7 @@ public Builder flattenMixins() { Set computedErrors = new LinkedHashSet<>(); for (Shape shape : getMixins().values()) { - shape.asOperationShape().ifPresent(mixin -> computedErrors.addAll(mixin.getErrors())); + shape.asOperationShape().ifPresent(mixin -> computedErrors.addAll(mixin.getErrorsSet())); } computedErrors.addAll(errors.peek()); diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ServiceShape.java b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ServiceShape.java index cf635c0698c..3b1b47836a4 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ServiceShape.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ServiceShape.java @@ -4,7 +4,6 @@ */ package software.amazon.smithy.model.shapes; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; @@ -15,6 +14,7 @@ import java.util.Optional; import java.util.Set; import software.amazon.smithy.utils.BuilderRef; +import software.amazon.smithy.utils.ListUtils; import software.amazon.smithy.utils.ToSmithyBuilder; /** @@ -26,8 +26,8 @@ public final class ServiceShape extends EntityShape implements ToSmithyBuilder rename; private final Map introducedRename; - private final List errors; - private final List introducedErrors; + private final Set errors; + private final Set introducedErrors; private ServiceShape(Builder builder) { super(builder); @@ -51,7 +51,7 @@ private ServiceShape(Builder builder) { computedVersion = mixin.version; } computedRename.putAll(mixin.getRename()); - computedErrors.addAll(mixin.getErrors()); + computedErrors.addAll(mixin.getErrorsSet()); } } @@ -67,7 +67,7 @@ private ServiceShape(Builder builder) { version = computedVersion; rename = Collections.unmodifiableMap(computedRename); - errors = Collections.unmodifiableList(new ArrayList<>(computedErrors)); + errors = Collections.unmodifiableSet(new LinkedHashSet<>(computedErrors)); } } @@ -150,6 +150,11 @@ public Map getIntroducedRename() { return introducedRename; } + @Deprecated + public List getErrors() { + return ListUtils.copyOf(errors); + } + /** *

Gets a list of the common errors that can be encountered by * every operation in the service.

@@ -160,10 +165,15 @@ public Map getIntroducedRename() { * * @return Returns the errors. */ - public List getErrors() { + public Set getErrorsSet() { return errors; } + @Deprecated + public List getIntroducedErrors() { + return ListUtils.copyOf(introducedErrors); + } + /** * Gets the list of common errors introduced by the shape and not * inherited from mixins. These errors can be encountered by every @@ -175,7 +185,7 @@ public List getErrors() { * * @return Returns the introduced service errors. */ - public List getIntroducedErrors() { + public Set getIntroducedErrorsSet() { return introducedErrors; } @@ -204,7 +214,7 @@ public String getContextualName(ToShapeId shape) { public static final class Builder extends EntityShape.Builder { private String version = ""; private final BuilderRef> rename = BuilderRef.forOrderedMap(); - private final BuilderRef> errors = BuilderRef.forList(); + private final BuilderRef> errors = BuilderRef.forOrderedSet(); @Override public ServiceShape build() { @@ -328,7 +338,7 @@ public Builder flattenMixins() { flatVersion = mixin.version; } flatRename.putAll(mixin.getRename()); - flatErrors.addAll(mixin.getErrors()); + flatErrors.addAll(mixin.getErrorsSet()); } } diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java index e98507b2e4c..6773c71c674 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java @@ -807,7 +807,7 @@ public Void serviceShape(ServiceShape shape) { codeWriter.writeOptionalIdList("operations", shape.getIntroducedOperations()); codeWriter.writeOptionalIdList("resources", shape.getIntroducedResources()); - codeWriter.writeOptionalIdList("errors", shape.getIntroducedErrors()); + codeWriter.writeOptionalIdList("errors", shape.getIntroducedErrorsSet()); if (!shape.getIntroducedRename().isEmpty()) { codeWriter.openBlock("rename: {", "}", () -> { for (Map.Entry entry : shape.getIntroducedRename().entrySet()) { @@ -866,7 +866,7 @@ public Void operationShape(OperationShape shape) { List mixinMembers = new ArrayList<>(); mixinMembers.addAll(writeInlineableProperty("input", shape.getInputShape(), InputTrait.ID)); mixinMembers.addAll(writeInlineableProperty("output", shape.getOutputShape(), OutputTrait.ID)); - codeWriter.writeOptionalIdList("errors", shape.getIntroducedErrors()); + codeWriter.writeOptionalIdList("errors", shape.getIntroducedErrorsSet()); codeWriter.closeBlock("}"); codeWriter.write(""); applyIntroducedTraits(mixinMembers); diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/transform/CopyServiceErrorsToOperationsTransform.java b/smithy-model/src/main/java/software/amazon/smithy/model/transform/CopyServiceErrorsToOperationsTransform.java index 54684137bb8..a9f43127cb6 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/transform/CopyServiceErrorsToOperationsTransform.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/transform/CopyServiceErrorsToOperationsTransform.java @@ -26,15 +26,15 @@ final class CopyServiceErrorsToOperationsTransform { } Model transform(ModelTransformer transformer, Model model) { - if (forService.getErrors().isEmpty()) { + if (forService.getErrorsSet().isEmpty()) { return model; } Set toReplace = new HashSet<>(); TopDownIndex topDownIndex = TopDownIndex.of(model); for (OperationShape operation : topDownIndex.getContainedOperations(forService)) { - Set errors = new LinkedHashSet<>(operation.getErrors()); - errors.addAll(forService.getErrors()); + Set errors = new LinkedHashSet<>(operation.getErrorsSet()); + errors.addAll(forService.getErrorsSet()); toReplace.add(operation.toBuilder().errors(errors).build()); } diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/transform/DeconflictErrorsWithSharedStatusCode.java b/smithy-model/src/main/java/software/amazon/smithy/model/transform/DeconflictErrorsWithSharedStatusCode.java index 72665c77817..6aa378cca4e 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/transform/DeconflictErrorsWithSharedStatusCode.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/transform/DeconflictErrorsWithSharedStatusCode.java @@ -49,7 +49,7 @@ Model transform(ModelTransformer transformer, Model model) { // Collect errors that share the same status code. Map> statusCodesToErrors = new HashMap<>(); - for (ShapeId errorId : operation.getErrors()) { + for (ShapeId errorId : operation.getErrorsSet()) { StructureShape error = model.expectShape(errorId, StructureShape.class); Integer statusCode = error.hasTrait(HttpErrorTrait.ID) ? error.getTrait(HttpErrorTrait.class).get().getCode() diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/transform/plugins/CleanOperationStructures.java b/smithy-model/src/main/java/software/amazon/smithy/model/transform/plugins/CleanOperationStructures.java index 27af75d7967..679b0231cee 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/transform/plugins/CleanOperationStructures.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/transform/plugins/CleanOperationStructures.java @@ -73,10 +73,10 @@ private OperationShape.Builder transformErrors( OperationShape operation, OperationShape.Builder builder ) { - Set errors = new HashSet<>(operation.getErrors()); + Set errors = new HashSet<>(operation.getErrorsSet()); errors.removeAll(removed); - if (errors.size() != operation.getErrors().size()) { + if (errors.size() != operation.getErrorsSet().size()) { if (builder == null) { builder = operation.toBuilder(); } diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/ExamplesTraitValidator.java b/smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/ExamplesTraitValidator.java index 6b3c8017063..5a8d87f06e2 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/ExamplesTraitValidator.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/ExamplesTraitValidator.java @@ -78,7 +78,7 @@ private List validateExamples(Model model, OperationShape shape Optional errorShape = model.getShape(errorExample.getShapeId()); if (errorShape.isPresent() && ( // The error is directly bound to the operation. - shape.getErrors().contains(errorExample.getShapeId()) + shape.getErrorsSet().contains(errorExample.getShapeId()) // The error is bound to all services that contain the operation. || servicesContainError(model, shape, errorExample.getShapeId()))) { NodeValidationVisitor validator = createVisitor( @@ -118,7 +118,7 @@ private boolean servicesContainError(Model model, OperationShape shape, ShapeId // We've already checked if the operation contains the error, // so a service having no errors means we've failed. - if (service.getErrors().isEmpty() || !service.getErrors().contains(errorId)) { + if (service.getErrorsSet().isEmpty() || !service.getErrorsSet().contains(errorId)) { return false; } } diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/loader/IdlModelLoaderTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/loader/IdlModelLoaderTest.java index 9a5798c3302..71db623af80 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/loader/IdlModelLoaderTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/loader/IdlModelLoaderTest.java @@ -45,8 +45,8 @@ import software.amazon.smithy.model.validation.ValidatedResult; import software.amazon.smithy.model.validation.ValidatedResultException; import software.amazon.smithy.model.validation.ValidationEvent; -import software.amazon.smithy.utils.ListUtils; import software.amazon.smithy.utils.MapUtils; +import software.amazon.smithy.utils.SetUtils; public class IdlModelLoaderTest { @Test @@ -206,8 +206,8 @@ public void properlyLoadsOperationsWithUseStatements() { assertThat(model.expectShape(ShapeId.from("smithy.example#Local"), OperationShape.class).getInput(), equalTo(Optional.of(ShapeId.from("smithy.example.nested#A")))); - assertThat(model.expectShape(ShapeId.from("smithy.example#Local"), OperationShape.class).getErrors(), - equalTo(ListUtils.of(ShapeId.from("smithy.example.nested#C")))); + assertThat(model.expectShape(ShapeId.from("smithy.example#Local"), OperationShape.class).getErrorsSet(), + equalTo(SetUtils.of(ShapeId.from("smithy.example.nested#C")))); Map identifiers = model.expectShape( ShapeId.from("smithy.example.nested#Resource"), diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/loader/ModelAssemblerTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/loader/ModelAssemblerTest.java index b8518dc2059..4a180b4e224 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/loader/ModelAssemblerTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/loader/ModelAssemblerTest.java @@ -1089,7 +1089,7 @@ public void forwardReferencesAreOrdered() { .unwrap(); ShapeId service = ShapeId.from("smithy.example#Example"); - assertThat(model.expectShape(service, ServiceShape.class).getErrors(), + assertThat(model.expectShape(service, ServiceShape.class).getErrorsSet(), contains(ShapeId.from("smithy.example#Error1"), ShapeId.from("smithy.example#Error2"), ShapeId.from("smithy.example#Error3"), diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/shapes/ModelSerializerTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/shapes/ModelSerializerTest.java index bd4f14a81d2..b850c5de4dc 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/shapes/ModelSerializerTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/shapes/ModelSerializerTest.java @@ -81,6 +81,22 @@ private void testV1DowngradeSerialization(Path path, Path expectedV1Path) { Node.assertEquals(model1, expectedDowngrade); } + @Test + public void testSerializationDoesntChangeErrorSemanticEquality() throws URISyntaxException { + String filename = "ast-serialization/out-of-order-errors.json"; + Path path = Paths.get(SmithyIdlModelSerializer.class.getResource(filename).toURI()); + Model model = Model.assembler().addImport(path).assemble().unwrap(); + + ModelSerializer serializer = ModelSerializer.builder().build(); + ObjectNode serialized = serializer.serialize(model); + Model roundTrippedModel = Model.assembler() + .addUnparsedModel(path.toString(), Node.printJson(serialized)) + .assemble() + .unwrap(); + + assertThat(roundTrippedModel, equalTo(model)); + } + @Test public void serializesModels() { Model model = Model.assembler() diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/transform/CopyServiceErrorsToOperationsTransformTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/transform/CopyServiceErrorsToOperationsTransformTest.java index f3c57223198..7e523be48b5 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/transform/CopyServiceErrorsToOperationsTransformTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/transform/CopyServiceErrorsToOperationsTransformTest.java @@ -47,7 +47,7 @@ public void copiesErrors() { assertThat(operation2, Matchers.equalTo(result.expectShape(operation2.getId()))); // Make sure service errors were copied to the operation bound within it. - assertThat(result.expectShape(operation1.getId(), OperationShape.class).getErrors(), + assertThat(result.expectShape(operation1.getId(), OperationShape.class).getErrorsSet(), Matchers.containsInAnyOrder(errorShape1.getId(), errorShape2.getId())); } } diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/transform/ModelTransformerTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/transform/ModelTransformerTest.java index 790ab305519..507b1115b4e 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/transform/ModelTransformerTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/transform/ModelTransformerTest.java @@ -51,8 +51,8 @@ public void discoversOnRemoveClassesWithSpi() { Matchers.equalTo(Optional.of(UnitTypeTrait.UNIT))); assertThat(result.expectShape(operation).asOperationShape().map(OperationShape::getOutputShape), Matchers.equalTo(Optional.of(UnitTypeTrait.UNIT))); - assertThat(result.expectShape(operation).asOperationShape().map(OperationShape::getErrors), - Matchers.equalTo(Optional.of(Collections.emptyList()))); + assertThat(result.expectShape(operation).asOperationShape().map(OperationShape::getErrorsSet), + Matchers.equalTo(Optional.of(Collections.emptySet()))); } @Test diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/transform/RemoveShapesTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/transform/RemoveShapesTest.java index 195d806658d..d19caa1f96f 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/transform/RemoveShapesTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/transform/RemoveShapesTest.java @@ -208,7 +208,7 @@ public void removesOperationComponentsWhenStructureRemoved() { assertEquals(1, result.shapes().count()); assertFalse(result.expectShape(operationId, OperationShape.class).getInput().isPresent()); assertFalse(result.expectShape(operationId, OperationShape.class).getOutput().isPresent()); - assertTrue(result.expectShape(operationId, OperationShape.class).getErrors().isEmpty()); + assertTrue(result.expectShape(operationId, OperationShape.class).getErrorsSet().isEmpty()); } @Test diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/ast-serialization/out-of-order-errors.json b/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/ast-serialization/out-of-order-errors.json new file mode 100644 index 00000000000..cbf2e406c42 --- /dev/null +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/ast-serialization/out-of-order-errors.json @@ -0,0 +1,61 @@ +{ + "smithy": "2.0", + "shapes": { + "smithy.example#ErrorA": { + "type": "structure", + "members": {}, + "traits": { + "smithy.api#error": "client" + } + }, + "smithy.example#ErrorB": { + "type": "structure", + "members": {}, + "traits": { + "smithy.api#error": "client" + } + }, + "smithy.example#ErrorC": { + "type": "structure", + "members": {}, + "traits": { + "smithy.api#error": "client" + } + }, + "smithy.example#ErrorD": { + "type": "structure", + "members": {}, + "traits": { + "smithy.api#error": "client" + } + }, + "smithy.example#Operation": { + "type": "operation", + "input": { + "target": "smithy.api#Unit" + }, + "output": { + "target": "smithy.api#Unit" + }, + "errors": [ + { + "target": "smithy.example#ErrorD" + }, + { + "target": "smithy.example#ErrorC" + } + ] + }, + "smithy.example#Service": { + "type": "service", + "errors": [ + { + "target": "smithy.example#ErrorB" + }, + { + "target": "smithy.example#ErrorA" + } + ] + } + } +} diff --git a/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/mappers/CheckForPrefixHeaders.java b/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/mappers/CheckForPrefixHeaders.java index a051052d4c0..ae7d055c2ad 100644 --- a/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/mappers/CheckForPrefixHeaders.java +++ b/smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/mappers/CheckForPrefixHeaders.java @@ -43,7 +43,7 @@ public void before(Context context, OpenApi.Builder builder) { context.getModel().shapes(OperationShape.class).forEach(operation -> { check(context, httpBindings.getRequestBindings(operation, HttpBinding.Location.PREFIX_HEADERS)); checkForResponseHeaders(context, httpBindings, operation); - operation.getErrors().forEach(error -> checkForResponseHeaders(context, httpBindings, error)); + operation.getErrorsSet().forEach(error -> checkForResponseHeaders(context, httpBindings, error)); }); } diff --git a/smithy-waiters/src/main/java/software/amazon/smithy/waiters/WaiterMatcherValidator.java b/smithy-waiters/src/main/java/software/amazon/smithy/waiters/WaiterMatcherValidator.java index fecb47c8df3..d15f9f0ad98 100644 --- a/smithy-waiters/src/main/java/software/amazon/smithy/waiters/WaiterMatcherValidator.java +++ b/smithy-waiters/src/main/java/software/amazon/smithy/waiters/WaiterMatcherValidator.java @@ -80,7 +80,7 @@ public List visitErrorType(Matcher.ErrorTypeMember errorType) { // defined in the actual model. String error = errorType.getValue(); - for (ShapeId errorId : operation.getErrors()) { + for (ShapeId errorId : operation.getErrorsSet()) { if (error.equals(errorId.toString()) || error.equals(errorId.getName())) { return events; } @@ -90,7 +90,7 @@ public List visitErrorType(Matcher.ErrorTypeMember errorType) { String.format( "errorType '%s' not found on operation. This operation defines the following errors: %s", error, - operation.getErrors()), + operation.getErrorsSet()), INVALID_ERROR_TYPE, waiterName, String.valueOf(acceptorIndex));