Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn don't fail on additional properties #374

Merged
merged 1 commit into from
Apr 16, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -15,22 +15,19 @@

package software.amazon.smithy.aws.iam.traits;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.node.StringNode;
import software.amazon.smithy.model.node.ToNode;
import software.amazon.smithy.utils.ListUtils;
import software.amazon.smithy.utils.SmithyBuilder;
import software.amazon.smithy.utils.ToSmithyBuilder;

public final class ConditionKeyDefinition implements ToNode, ToSmithyBuilder<ConditionKeyDefinition> {
private static final String TYPE = "type";
private static final String DOCUMENTATION = "documentation";
private static final String EXTERNAL_DOCUMENTATION = "externalDocumentation";
private static final List<String> SUPPORTED_PROPERTIES = ListUtils.of(TYPE, DOCUMENTATION, EXTERNAL_DOCUMENTATION);

private final String type;
private final String documentation;
@@ -48,7 +45,6 @@ public static Builder builder() {

public static ConditionKeyDefinition fromNode(Node value) {
ObjectNode objectNode = value.expectObjectNode();
objectNode.warnIfAdditionalProperties(SUPPORTED_PROPERTIES);
Builder builder = builder()
.type(objectNode.expectStringMember(TYPE).getValue());
objectNode.getStringMember(DOCUMENTATION).map(StringNode::getValue)
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@

package software.amazon.smithy.aws.traits;

import java.util.List;
import java.util.Optional;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.ObjectNode;
@@ -24,7 +23,6 @@
import software.amazon.smithy.model.traits.AbstractTrait;
import software.amazon.smithy.model.traits.AbstractTraitBuilder;
import software.amazon.smithy.model.traits.Trait;
import software.amazon.smithy.utils.ListUtils;
import software.amazon.smithy.utils.ToSmithyBuilder;

/**
@@ -36,7 +34,6 @@ public final class ArnReferenceTrait extends AbstractTrait implements ToSmithyBu
private static final String TYPE = "type";
private static final String SERVICE = "service";
private static final String RESOURCE = "resource";
private static final List<String> PROPERTIES = ListUtils.of(TYPE, SERVICE, RESOURCE);

private String type;
private ShapeId service;
@@ -58,7 +55,6 @@ public Provider() {
public Trait createTrait(ShapeId target, Node value) {
ObjectNode objectNode = value.expectObjectNode();
Builder builder = builder();
objectNode.warnIfAdditionalProperties(PROPERTIES);
objectNode.getStringMember(TYPE)
.map(StringNode::getValue)
.ifPresent(builder::type);
Original file line number Diff line number Diff line change
@@ -27,7 +27,6 @@
import software.amazon.smithy.model.traits.AbstractTrait;
import software.amazon.smithy.model.traits.AbstractTraitBuilder;
import software.amazon.smithy.model.traits.Trait;
import software.amazon.smithy.utils.ListUtils;
import software.amazon.smithy.utils.SmithyBuilder;
import software.amazon.smithy.utils.ToSmithyBuilder;

@@ -42,7 +41,6 @@ public final class ArnTrait extends AbstractTrait implements ToSmithyBuilder<Arn
private static final String ABSOLUTE = "absolute";
private static final String NO_REGION = "noRegion";
private static final String NO_ACCOUNT = "noAccount";
private static final List<String> PROPERTIES = ListUtils.of(TEMPLATE, ABSOLUTE, NO_REGION, NO_ACCOUNT);
private static final Pattern PATTERN = Pattern.compile("\\{([^}]+)}");

private final boolean noRegion;
@@ -74,7 +72,6 @@ public Provider() {
public Trait createTrait(ShapeId target, Node value) {
Builder builder = builder();
ObjectNode objectNode = value.expectObjectNode();
objectNode.warnIfAdditionalProperties(PROPERTIES);
builder.template(objectNode.expectStringMember(TEMPLATE).getValue());
builder.absolute(objectNode.getBooleanMemberOrDefault(ABSOLUTE));
builder.noRegion(objectNode.getBooleanMemberOrDefault(NO_REGION));
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@

package software.amazon.smithy.aws.traits;

import java.util.Arrays;
import java.util.Locale;
import java.util.Optional;
import software.amazon.smithy.model.SourceException;
@@ -60,9 +59,6 @@ public Provider() {
@Override
public Trait createTrait(ShapeId target, Node value) {
ObjectNode objectNode = value.expectObjectNode();
objectNode.warnIfAdditionalProperties(Arrays.asList(
"sdkId", "arnNamespace", "cloudFormationName", "cloudTrailEventSource", "abbreviation"));

Builder builder = builder();
String sdkId = objectNode.getStringMember("sdkId")
.map(StringNode::getValue)
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ public Provider() {

@Override
public Trait createTrait(ShapeId target, Node value) {
ObjectNode objectNode = value.expectObjectNode().warnIfAdditionalProperties(ListUtils.of(PROVIDER_ARNS));
ObjectNode objectNode = value.expectObjectNode();
return builder()
.providerArns(objectNode.expectArrayMember(PROVIDER_ARNS).getElementsAs(StringNode::getValue))
.build();
Original file line number Diff line number Diff line change
@@ -15,14 +15,12 @@

package software.amazon.smithy.aws.traits.auth;

import java.util.Set;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.AbstractTrait;
import software.amazon.smithy.model.traits.AbstractTraitBuilder;
import software.amazon.smithy.model.traits.Trait;
import software.amazon.smithy.utils.SetUtils;
import software.amazon.smithy.utils.SmithyBuilder;
import software.amazon.smithy.utils.ToSmithyBuilder;

@@ -33,7 +31,6 @@ public final class SigV4Trait extends AbstractTrait implements ToSmithyBuilder<S

public static final ShapeId ID = ShapeId.from("aws.auth#sigv4");
private static final String NAME = "name";
private static final Set<String> PROPERTIES = SetUtils.of(NAME);

private final String name;

@@ -90,7 +87,6 @@ public Provider() {
public Trait createTrait(ShapeId target, Node value) {
Builder builder = builder().sourceLocation(value);
ObjectNode objectNode = value.expectObjectNode();
objectNode.warnIfAdditionalProperties(PROPERTIES);
builder.name(objectNode.expectStringMember(NAME).getValue());
return builder.build();
}
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@

package software.amazon.smithy.aws.traits.clientendpointdiscovery;

import java.util.Collections;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ShapeId;
@@ -90,8 +89,6 @@ public Provider() {
@Override
public ClientDiscoveredEndpointTrait createTrait(ShapeId target, Node value) {
ObjectNode objectNode = value.expectObjectNode();
objectNode.warnIfAdditionalProperties(Collections.singletonList(REQUIRED));

return builder()
.required(objectNode.getBooleanMemberOrDefault(REQUIRED, true))
.build();
Original file line number Diff line number Diff line change
@@ -15,9 +15,6 @@

package software.amazon.smithy.aws.traits.clientendpointdiscovery;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import software.amazon.smithy.model.node.Node;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ShapeId;
@@ -34,7 +31,6 @@ public final class ClientEndpointDiscoveryTrait extends AbstractTrait

private static final String OPERATION = "operation";
private static final String ERROR = "error";
private static final List<String> PROPERTIES = Collections.unmodifiableList(Arrays.asList(OPERATION, ERROR));

private final ShapeId operation;
private final ShapeId error;
@@ -139,8 +135,6 @@ public Provider() {
@Override
public ClientEndpointDiscoveryTrait createTrait(ShapeId target, Node value) {
ObjectNode objectNode = value.expectObjectNode();
objectNode.warnIfAdditionalProperties(PROPERTIES);

return builder()
.operation(objectNode.expectStringMember(OPERATION).expectShapeId())
.error(objectNode.expectStringMember(ERROR).expectShapeId())
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ enum AstModelLoader {
TYPE, "version", "operations", "resources", TRAITS);

void load(ObjectNode model, LoaderVisitor visitor) {
model.expectNoAdditionalProperties(TOP_LEVEL_PROPERTIES);
visitor.checkForAdditionalProperties(model, null, TOP_LEVEL_PROPERTIES);
loadMetadata(model, visitor);
loadShapes(model, visitor);
}
@@ -185,7 +185,7 @@ private void loadShape(ShapeId id, String type, ObjectNode value, LoaderVisitor
loadOperation(id, value, visitor);
break;
case "apply":
value.expectNoAdditionalProperties(APPLY_PROPERTIES);
visitor.checkForAdditionalProperties(value, id, APPLY_PROPERTIES);
applyTraits(id, value.expectObjectMember(TRAITS), visitor);
break;
default:
@@ -205,7 +205,7 @@ private void applyShapeTraits(ShapeId id, ObjectNode node, LoaderVisitor visitor
}

private void loadMember(LoaderVisitor visitor, ShapeId id, ObjectNode targetNode) {
targetNode.expectNoAdditionalProperties(MEMBER_PROPERTIES);
visitor.checkForAdditionalProperties(targetNode, id, MEMBER_PROPERTIES);
MemberShape.Builder builder = MemberShape.builder().source(targetNode.getSourceLocation()).id(id);
ShapeId target = targetNode.expectStringMember(TARGET).expectShapeId();
builder.target(target);
@@ -219,52 +219,52 @@ private void loadCollection(
CollectionShape.Builder builder,
LoaderVisitor visitor
) {
node.expectNoAdditionalProperties(COLLECTION_PROPERTY_NAMES);
visitor.checkForAdditionalProperties(node, id, COLLECTION_PROPERTY_NAMES);
applyShapeTraits(id, node, visitor);
loadMember(visitor, id.withMember("member"), node.expectObjectMember("member"));
visitor.onShape(builder.id(id).source(node.getSourceLocation()));
}

private void loadMap(ShapeId id, ObjectNode node, LoaderVisitor visitor) {
node.expectNoAdditionalProperties(MAP_PROPERTY_NAMES);
visitor.checkForAdditionalProperties(node, id, MAP_PROPERTY_NAMES);
loadMember(visitor, id.withMember("key"), node.expectObjectMember("key"));
loadMember(visitor, id.withMember("value"), node.expectObjectMember("value"));
applyShapeTraits(id, node, visitor);
visitor.onShape(MapShape.builder().id(id).source(node.getSourceLocation()));
}

private void loadOperation(ShapeId operationShapeId, ObjectNode node, LoaderVisitor visitor) {
node.expectNoAdditionalProperties(OPERATION_PROPERTY_NAMES);
applyShapeTraits(operationShapeId, node, visitor);
private void loadOperation(ShapeId id, ObjectNode node, LoaderVisitor visitor) {
visitor.checkForAdditionalProperties(node, id, OPERATION_PROPERTY_NAMES);
applyShapeTraits(id, node, visitor);
OperationShape.Builder builder = OperationShape.builder()
.id(operationShapeId)
.id(id)
.source(node.getSourceLocation())
.addErrors(loadOptionalTargetList(node, "errors"));
.addErrors(loadOptionalTargetList(visitor, id, node, "errors"));

loadOptionalTarget(node, "input").ifPresent(builder::input);
loadOptionalTarget(node, "output").ifPresent(builder::output);
loadOptionalTarget(visitor, id, node, "input").ifPresent(builder::input);
loadOptionalTarget(visitor, id, node, "output").ifPresent(builder::output);
visitor.onShape(builder);
}

private void loadResource(ShapeId id, ObjectNode node, LoaderVisitor visitor) {
node.expectNoAdditionalProperties(RESOURCE_PROPERTIES);
visitor.checkForAdditionalProperties(node, id, RESOURCE_PROPERTIES);
applyShapeTraits(id, node, visitor);
ResourceShape.Builder builder = ResourceShape.builder().id(id).source(node.getSourceLocation());
loadOptionalTarget(node, "put").ifPresent(builder::put);
loadOptionalTarget(node, "create").ifPresent(builder::create);
loadOptionalTarget(node, "read").ifPresent(builder::read);
loadOptionalTarget(node, "update").ifPresent(builder::update);
loadOptionalTarget(node, "delete").ifPresent(builder::delete);
loadOptionalTarget(node, "list").ifPresent(builder::list);
builder.operations(loadOptionalTargetList(node, "operations"));
builder.collectionOperations(loadOptionalTargetList(node, "collectionOperations"));
builder.resources(loadOptionalTargetList(node, "resources"));
loadOptionalTarget(visitor, id, node, "put").ifPresent(builder::put);
loadOptionalTarget(visitor, id, node, "create").ifPresent(builder::create);
loadOptionalTarget(visitor, id, node, "read").ifPresent(builder::read);
loadOptionalTarget(visitor, id, node, "update").ifPresent(builder::update);
loadOptionalTarget(visitor, id, node, "delete").ifPresent(builder::delete);
loadOptionalTarget(visitor, id, node, "list").ifPresent(builder::list);
builder.operations(loadOptionalTargetList(visitor, id, node, "operations"));
builder.collectionOperations(loadOptionalTargetList(visitor, id, node, "collectionOperations"));
builder.resources(loadOptionalTargetList(visitor, id, node, "resources"));

// Load identifiers and resolve forward references.
node.getObjectMember("identifiers").ifPresent(ids -> {
for (Map.Entry<StringNode, Node> entry : ids.getMembers().entrySet()) {
String name = entry.getKey().getValue();
ShapeId target = loadReferenceBody(entry.getValue());
ShapeId target = loadReferenceBody(visitor, id, entry.getValue());
builder.addIdentifier(name, target);
}
});
@@ -273,30 +273,30 @@ private void loadResource(ShapeId id, ObjectNode node, LoaderVisitor visitor) {
}

private void loadService(ShapeId id, ObjectNode node, LoaderVisitor visitor) {
node.expectNoAdditionalProperties(SERVICE_PROPERTIES);
visitor.checkForAdditionalProperties(node, id, SERVICE_PROPERTIES);
applyShapeTraits(id, node, visitor);
ServiceShape.Builder builder = new ServiceShape.Builder().id(id).source(node.getSourceLocation());
builder.version(node.expectStringMember("version").getValue());
builder.operations(loadOptionalTargetList(node, "operations"));
builder.resources(loadOptionalTargetList(node, "resources"));
builder.operations(loadOptionalTargetList(visitor, id, node, "operations"));
builder.resources(loadOptionalTargetList(visitor, id, node, "resources"));
visitor.onShape(builder);
}

private void loadSimpleShape(
ShapeId id, ObjectNode node, AbstractShapeBuilder builder, LoaderVisitor visitor) {
node.expectNoAdditionalProperties(SIMPLE_PROPERTY_NAMES);
visitor.checkForAdditionalProperties(node, id, SIMPLE_PROPERTY_NAMES);
applyShapeTraits(id, node, visitor);
visitor.onShape(builder.id(id).source(node.getSourceLocation()));
}

private void loadStructure(ShapeId id, ObjectNode node, LoaderVisitor visitor) {
node.expectNoAdditionalProperties(STRUCTURE_AND_UNION_PROPERTY_NAMES);
visitor.checkForAdditionalProperties(node, id, STRUCTURE_AND_UNION_PROPERTY_NAMES);
visitor.onShape(StructureShape.builder().id(id).source(node.getSourceLocation()));
finishLoadingStructOrUnionMembers(id, node, visitor);
}

private void loadUnion(ShapeId id, ObjectNode node, LoaderVisitor visitor) {
node.expectNoAdditionalProperties(STRUCTURE_AND_UNION_PROPERTY_NAMES);
visitor.checkForAdditionalProperties(node, id, STRUCTURE_AND_UNION_PROPERTY_NAMES);
visitor.onShape(UnionShape.builder().id(id).source(node.getSourceLocation()));
finishLoadingStructOrUnionMembers(id, node, visitor);
}
@@ -309,20 +309,22 @@ private void finishLoadingStructOrUnionMembers(ShapeId id, ObjectNode node, Load
}
}

private Optional<ShapeId> loadOptionalTarget(ObjectNode node, String member) {
return node.getObjectMember(member).map(this::loadReferenceBody);
private Optional<ShapeId> loadOptionalTarget(
LoaderVisitor visitor, ShapeId id, ObjectNode node, String member) {
return node.getObjectMember(member).map(r -> loadReferenceBody(visitor, id, r));
}

private ShapeId loadReferenceBody(Node reference) {
private ShapeId loadReferenceBody(LoaderVisitor visitor, ShapeId id, Node reference) {
ObjectNode referenceObject = reference.expectObjectNode();
referenceObject.expectNoAdditionalProperties(REFERENCE_PROPERTIES);
visitor.checkForAdditionalProperties(referenceObject, id, REFERENCE_PROPERTIES);
return referenceObject.expectStringMember(TARGET).expectShapeId();
}

private List<ShapeId> loadOptionalTargetList(ObjectNode node, String member) {
private List<ShapeId> loadOptionalTargetList(
LoaderVisitor visitor, ShapeId id, ObjectNode node, String member) {
return node.getArrayMember(member)
.map(array -> array.getElements().stream()
.map(this::loadReferenceBody)
.map(e -> loadReferenceBody(visitor, id, e))
.collect(Collectors.toList()))
.orElseGet(Collections::emptyList);
}
Original file line number Diff line number Diff line change
@@ -885,7 +885,7 @@ private void parseService() {
.source(sourceLocation);

ObjectNode shapeNode = parseObjectNode(expect(LBRACE).getSourceLocation(), RBRACE);
shapeNode.warnIfAdditionalProperties(SERVICE_PROPERTY_NAMES);
visitor.checkForAdditionalProperties(shapeNode, shapeId, SERVICE_PROPERTY_NAMES);
builder.version(shapeNode.expectStringMember(VERSION_KEY).getValue());
optionalIdList(shapeNode, shapeId.getNamespace(), OPERATIONS_KEY).forEach(builder::addOperation);
optionalIdList(shapeNode, shapeId.getNamespace(), RESOURCES_KEY).forEach(builder::addResource);
@@ -913,7 +913,7 @@ private void parseResource() {
visitor.onShape(builder);
ObjectNode shapeNode = parseObjectNode(expect(LBRACE).getSourceLocation(), RBRACE);

shapeNode.warnIfAdditionalProperties(RESOURCE_PROPERTY_NAMES);
visitor.checkForAdditionalProperties(shapeNode, shapeId, RESOURCE_PROPERTY_NAMES);
optionalId(shapeNode, shapeId.getNamespace(), PUT_KEY).ifPresent(builder::put);
optionalId(shapeNode, shapeId.getNamespace(), CREATE_KEY).ifPresent(builder::create);
optionalId(shapeNode, shapeId.getNamespace(), READ_KEY).ifPresent(builder::read);
@@ -945,7 +945,7 @@ private void parseOperation() {

Token opening = expect(LBRACE);
ObjectNode node = parseObjectNode(opening.getSourceLocation(), RBRACE);
node.expectNoAdditionalProperties(OPERATION_PROPERTY_NAMES);
visitor.checkForAdditionalProperties(node, id, OPERATION_PROPERTY_NAMES);
node.getStringMember("input").ifPresent(input -> {
onShapeTarget(input.getValue(), input, builder::input);
});
Loading