Skip to content

Commit ef91f06

Browse files
committed
Remove deprecated model versions
1 parent 2450b00 commit ef91f06

File tree

40 files changed

+123
-926
lines changed

40 files changed

+123
-926
lines changed

smithy-build/src/test/java/software/amazon/smithy/build/plugins/SourcesPluginTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public void copiesModelFromJarWithSourceProjection() {
6868
assertThat(manifestString, not(containsString("jar-import/d.json")));
6969
assertThat(manifest.getFileString("jar-import/a.smithy").get(), containsString("string A"));
7070
assertThat(manifest.getFileString("jar-import/b/b.smithy").get(), containsString("string B"));
71-
assertThat(manifest.getFileString("jar-import/b/c/c.json").get(), containsString("\"C\""));
71+
assertThat(manifest.getFileString("jar-import/b/c/c.json").get(), containsString("\"foo.baz#C\""));
7272
}
7373

7474
@Test
Binary file not shown.

smithy-model/src/main/java/software/amazon/smithy/model/loader/AstModelLoader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ enum AstModelLoader {
8585
private static final Set<String> SERVICE_PROPERTIES = SetUtils.of(
8686
TYPE, "version", "operations", "resources", TRAITS);
8787

88-
void load(ObjectNode model, StringNode version, LoaderVisitor visitor) {
88+
void load(ObjectNode model, LoaderVisitor visitor) {
8989
model.expectNoAdditionalProperties(TOP_LEVEL_PROPERTIES);
9090
visitor.onOpenFile(model.getSourceLocation().getFilename());
9191
loadMetadata(model, visitor);

smithy-model/src/main/java/software/amazon/smithy/model/loader/DeprecatedAstModelLoader.java

Lines changed: 0 additions & 356 deletions
This file was deleted.

smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlModelLoader.java

Lines changed: 76 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.util.ArrayList;
4242
import java.util.Arrays;
4343
import java.util.Collection;
44+
import java.util.Collections;
4445
import java.util.HashSet;
4546
import java.util.LinkedHashMap;
4647
import java.util.List;
@@ -50,6 +51,7 @@
5051
import java.util.Set;
5152
import java.util.function.Consumer;
5253
import java.util.function.Supplier;
54+
import java.util.stream.Collectors;
5355
import software.amazon.smithy.model.SourceLocation;
5456
import software.amazon.smithy.model.node.ArrayNode;
5557
import software.amazon.smithy.model.node.BooleanNode;
@@ -96,6 +98,25 @@
9698

9799
final class IdlModelLoader {
98100

101+
private static final String PUT_KEY = "put";
102+
private static final String CREATE_KEY = "create";
103+
private static final String READ_KEY = "read";
104+
private static final String UPDATE_KEY = "update";
105+
private static final String DELETE_KEY = "delete";
106+
private static final String LIST_KEY = "list";
107+
private static final String RESOURCES_KEY = "resources";
108+
private static final String OPERATIONS_KEY = "operations";
109+
private static final String COLLECTION_OPERATIONS_KEY = "collectionOperations";
110+
private static final String IDENTIFIERS_KEY = "identifiers";
111+
private static final String VERSION_KEY = "version";
112+
private static final String TYPE_KEY = "type";
113+
114+
static final Collection<String> RESOURCE_PROPERTY_NAMES = ListUtils.of(
115+
TYPE_KEY, CREATE_KEY, READ_KEY, UPDATE_KEY, DELETE_KEY, LIST_KEY,
116+
IDENTIFIERS_KEY, RESOURCES_KEY, OPERATIONS_KEY, PUT_KEY, COLLECTION_OPERATIONS_KEY);
117+
static final List<String> SERVICE_PROPERTY_NAMES = ListUtils.of(
118+
TYPE_KEY, VERSION_KEY, OPERATIONS_KEY, RESOURCES_KEY);
119+
99120
// Top-level statements
100121
private static final Set<String> STATEMENTS = SetUtils.of(
101122
"namespace", "use", "service", "operation", "resource", "structure", "union",
@@ -119,7 +140,6 @@ final class IdlModelLoader {
119140
private final SmithyModelLexer lexer;
120141
private final LoaderVisitor visitor;
121142
private final List<Pair<String, Node>> pendingTraits = new ArrayList<>();
122-
private final Set<VersionFeature> features = new HashSet<>();
123143

124144
private Token current;
125145
private DocComment pendingDocComment;
@@ -148,64 +168,6 @@ private IdlModelLoader(String filename, SmithyModelLexer lexer, LoaderVisitor vi
148168
}
149169
}
150170

151-
enum VersionFeature {
152-
ALLOW_USE_BEFORE_NAMESPACE {
153-
@Override
154-
void validate(IdlModelLoader loader) {
155-
if (loader.namespace == null && !loader.features.contains(this)) {
156-
raise(loader, "Use statements must appear after a namespace is defined");
157-
}
158-
}
159-
},
160-
161-
ALLOW_MULTIPLE_NAMESPACES {
162-
@Override
163-
void validate(IdlModelLoader loader) {
164-
if (loader.namespace != null && !loader.features.contains(this)) {
165-
raise(loader, format(
166-
"Only a single namespace can be declared per/file. The previous namespace was "
167-
+ "set to `%s`.", loader.namespace));
168-
}
169-
}
170-
},
171-
172-
ALLOW_METADATA_AFTER_NAMESPACE {
173-
@Override
174-
void validate(IdlModelLoader loader) {
175-
if (loader.namespace != null && !loader.features.contains(this)) {
176-
raise(loader, "Metadata statements must appear before a namespace statement");
177-
}
178-
}
179-
},
180-
181-
ALLOW_MULTIPLE_VERSIONS {
182-
@Override
183-
void validate(IdlModelLoader loader) {
184-
if (loader.definedVersion != null && !loader.features.contains(this)) {
185-
raise(loader, "Cannot define multiple versions in the same file");
186-
}
187-
}
188-
};
189-
190-
abstract void validate(IdlModelLoader loader);
191-
192-
// Halts parsing if a version has been explicitly set, otherwise
193-
// adds a WARNING event.
194-
void raise(IdlModelLoader loader, String message) {
195-
if (loader.definedVersion != null) {
196-
throw loader.syntax(message);
197-
}
198-
199-
loader.visitor.onError(ValidationEvent.builder()
200-
.eventId(Validator.MODEL_ERROR)
201-
.severity(Severity.WARNING)
202-
.sourceLocation(loader.current)
203-
.message("Detected deprecated IDL features that will break in future versions "
204-
+ "of Smithy: " + message)
205-
.build());
206-
}
207-
}
208-
209171
private enum TraitValueType { SHAPE, MEMBER, APPLY }
210172

211173
/**
@@ -312,7 +274,11 @@ private void parseStatement(Token token) {
312274
}
313275

314276
private void parseNamespace() {
315-
VersionFeature.ALLOW_MULTIPLE_NAMESPACES.validate(this);
277+
if (namespace != null) {
278+
throw syntax("Only a single namespace can be declared per/file. The previous namespace was set to "
279+
+ "`" + namespace + "`.");
280+
}
281+
316282
String parsedNamespace = expect(UNQUOTED).lexeme;
317283

318284
if (!ShapeId.isValidNamespace(parsedNamespace)) {
@@ -324,7 +290,9 @@ private void parseNamespace() {
324290
}
325291

326292
private void parseUseStatement() {
327-
VersionFeature.ALLOW_USE_BEFORE_NAMESPACE.validate(this);
293+
if (namespace == null) {
294+
throw syntax("Use statements must appear after a namespace is defined");
295+
}
328296

329297
if (definedShapes) {
330298
throw syntax("A use statement must come before any shape definition");
@@ -367,25 +335,23 @@ private void onVersion(Node value) {
367335
}
368336

369337
String parsedVersion = value.expectStringNode().getValue();
370-
VersionFeature.ALLOW_MULTIPLE_VERSIONS.validate(this);
338+
339+
if (definedVersion != null) {
340+
throw syntax("Cannot define multiple versions in the same file");
341+
}
371342

372343
if (!SmithyVersion.isSupported(parsedVersion)) {
373344
throw syntax(format("Invalid Smithy version number: %s", parsedVersion));
374345
}
375346

376347
definedVersion = parsedVersion;
377-
378-
// Enable old Smithy 0.4.0 features that were removed in 0.5.0.
379-
if (definedVersion.equals(SmithyVersion.VERSION_0_4_0.value)) {
380-
features.add(VersionFeature.ALLOW_USE_BEFORE_NAMESPACE);
381-
features.add(VersionFeature.ALLOW_MULTIPLE_NAMESPACES);
382-
features.add(VersionFeature.ALLOW_METADATA_AFTER_NAMESPACE);
383-
features.add(VersionFeature.ALLOW_MULTIPLE_VERSIONS);
384-
}
385348
}
386349

387350
private void parseMetadata() {
388-
VersionFeature.ALLOW_METADATA_AFTER_NAMESPACE.validate(this);
351+
if (namespace != null) {
352+
throw syntax("Metadata statements must appear before a namespace statement");
353+
}
354+
389355
definedMetadata = true;
390356

391357
// metadata key = value\n
@@ -822,20 +788,55 @@ private void parseService() {
822788
.source(sourceLocation);
823789

824790
ObjectNode shapeNode = parseObjectNode(expect(LBRACE).getSourceLocation(), RBRACE);
825-
shapeNode.warnIfAdditionalProperties(LoaderUtils.SERVICE_PROPERTY_NAMES);
826-
LoaderUtils.loadServiceObject(builder, shapeId, shapeNode);
791+
shapeNode.warnIfAdditionalProperties(SERVICE_PROPERTY_NAMES);
792+
builder.version(shapeNode.expectStringMember(VERSION_KEY).getValue());
793+
optionalIdList(shapeNode, shapeId.getNamespace(), OPERATIONS_KEY).forEach(builder::addOperation);
794+
optionalIdList(shapeNode, shapeId.getNamespace(), RESOURCES_KEY).forEach(builder::addResource);
827795
visitor.onShape(builder);
828796
expectNewline();
829797
}
830798

799+
static Optional<ShapeId> optionalId(ObjectNode node, String namespace, String name) {
800+
return node.getStringMember(name).map(stringNode -> stringNode.expectShapeId(namespace));
801+
}
802+
803+
static List<ShapeId> optionalIdList(ObjectNode node, String namespace, String name) {
804+
return node.getArrayMember(name)
805+
.map(array -> array.getElements().stream()
806+
.map(Node::expectStringNode)
807+
.map(s -> s.expectShapeId(namespace))
808+
.collect(Collectors.toList()))
809+
.orElseGet(Collections::emptyList);
810+
}
811+
831812
private void parseResource() {
832813
SourceLocation sourceLocation = currentLocation();
833814
ShapeId shapeId = parseShapeName();
834815
ResourceShape.Builder builder = ResourceShape.builder().id(shapeId).source(sourceLocation);
835816
visitor.onShape(builder);
836817
ObjectNode shapeNode = parseObjectNode(expect(LBRACE).getSourceLocation(), RBRACE);
837-
shapeNode.warnIfAdditionalProperties(LoaderUtils.RESOURCE_PROPERTY_NAMES);
838-
LoaderUtils.loadResourceObject(builder, shapeId, shapeNode, visitor);
818+
819+
shapeNode.warnIfAdditionalProperties(RESOURCE_PROPERTY_NAMES);
820+
optionalId(shapeNode, shapeId.getNamespace(), PUT_KEY).ifPresent(builder::put);
821+
optionalId(shapeNode, shapeId.getNamespace(), CREATE_KEY).ifPresent(builder::create);
822+
optionalId(shapeNode, shapeId.getNamespace(), READ_KEY).ifPresent(builder::read);
823+
optionalId(shapeNode, shapeId.getNamespace(), UPDATE_KEY).ifPresent(builder::update);
824+
optionalId(shapeNode, shapeId.getNamespace(), DELETE_KEY).ifPresent(builder::delete);
825+
optionalId(shapeNode, shapeId.getNamespace(), LIST_KEY).ifPresent(builder::list);
826+
optionalIdList(shapeNode, shapeId.getNamespace(), OPERATIONS_KEY).forEach(builder::addOperation);
827+
optionalIdList(shapeNode, shapeId.getNamespace(), RESOURCES_KEY).forEach(builder::addResource);
828+
optionalIdList(shapeNode, shapeId.getNamespace(), COLLECTION_OPERATIONS_KEY)
829+
.forEach(builder::addCollectionOperation);
830+
831+
// Load identifiers and resolve forward references.
832+
shapeNode.getObjectMember(IDENTIFIERS_KEY).ifPresent(ids -> {
833+
for (Map.Entry<StringNode, Node> entry : ids.getMembers().entrySet()) {
834+
String name = entry.getKey().getValue();
835+
StringNode target = entry.getValue().expectStringNode();
836+
visitor.onShapeTarget(target.getValue(), target, id -> builder.addIdentifier(name, id));
837+
}
838+
});
839+
839840
expectNewline();
840841
}
841842

smithy-model/src/main/java/software/amazon/smithy/model/loader/LoaderUtils.java

Lines changed: 0 additions & 102 deletions
This file was deleted.

smithy-model/src/main/java/software/amazon/smithy/model/loader/LoaderVisitor.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,21 @@ public void onNamespace(String namespace, FromSourceLocation source) {
220220
*/
221221
public void onShapeTarget(String target, FromSourceLocation sourceLocation, Consumer<ShapeId> resolver) {
222222
try {
223-
ShapeId expectedId = ShapeId.fromOptionalNamespace(namespace, target);
224-
if (namespace.equals(Prelude.NAMESPACE) || hasDefinedShape(expectedId) || target.contains("#")) {
223+
// Account for aliased shapes.
224+
if (useShapes.containsKey(target)) {
225+
resolver.accept(useShapes.get(target));
226+
return;
227+
}
228+
229+
// A namespace is not set when parsing metadata.
230+
ShapeId expectedId = namespace == null
231+
? ShapeId.from(target)
232+
: ShapeId.fromOptionalNamespace(namespace, target);
233+
234+
if (Objects.equals(namespace, Prelude.NAMESPACE) || hasDefinedShape(expectedId) || target.contains("#")) {
225235
// Account for previously seen shapes in this namespace, absolute shapes, and prelude namespaces
226236
// always resolve to prelude shapes.
227237
resolver.accept(expectedId);
228-
} else if (useShapes.containsKey(target)) {
229-
// Account for aliased shapes.
230-
resolver.accept(useShapes.get(target));
231238
} else {
232239
forwardReferenceResolvers.add(new ForwardReferenceResolver(expectedId, resolver));
233240
}

0 commit comments

Comments
 (0)