Skip to content

Commit 2159d71

Browse files
committed
Use DirectedCodegen
Migrate the code generator to use Smithy's new and recommended DirectedCodegen.
1 parent 5bf952a commit 2159d71

22 files changed

+849
-973
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CodegenVisitor.java

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

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/DirectedTypeScriptCodegen.java

Lines changed: 485 additions & 0 deletions
Large diffs are not rendered by default.

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/HttpProtocolTestGenerator.java

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,21 +124,6 @@ public HttpProtocolTestGenerator(
124124
this.context = context;
125125
}
126126

127-
public HttpProtocolTestGenerator(
128-
GenerationContext context,
129-
ProtocolGenerator protocolGenerator,
130-
TestFilter testFilter
131-
) {
132-
this(context, protocolGenerator, testFilter, (service, operation, testCase, typeScriptSettings) -> false);
133-
}
134-
135-
public HttpProtocolTestGenerator(
136-
GenerationContext context,
137-
ProtocolGenerator protocolGenerator
138-
) {
139-
this(context, protocolGenerator, (service, operation, testCase, typeScriptSettings) -> false);
140-
}
141-
142127
@Override
143128
public void run() {
144129
OperationIndex operationIndex = OperationIndex.of(model);
@@ -243,7 +228,7 @@ private void onlyIfProtocolMatches(HttpMalformedRequestTestCase testCase, Runnab
243228

244229
private void initializeWriterIfNeeded() {
245230
if (writer == null) {
246-
writer = context.getWriter();
231+
context.getWriterDelegator().useFileWriter(createTestCaseFilename(), writer -> this.writer = writer);
247232
writer.addDependency(TypeScriptDependency.AWS_SDK_TYPES);
248233
writer.addDependency(TypeScriptDependency.AWS_SDK_PROTOCOL_HTTP);
249234
// Add the template to each generated test.

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/ImportDeclarations.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,18 @@
2121
import java.util.Set;
2222
import java.util.TreeMap;
2323
import software.amazon.smithy.codegen.core.CodegenException;
24+
import software.amazon.smithy.codegen.core.ImportContainer;
25+
import software.amazon.smithy.codegen.core.Symbol;
2426
import software.amazon.smithy.utils.Pair;
2527
import software.amazon.smithy.utils.SmithyInternalApi;
2628

2729
/**
2830
* Internal class used for aggregating imports of a file.
2931
*/
3032
@SmithyInternalApi
31-
final class ImportDeclarations {
33+
final class ImportDeclarations implements ImportContainer {
3234

35+
private final String moduleNameString;
3336
private final Path relativize;
3437
private final Map<String, Pair<String, Ignore>> defaultImports = new TreeMap<>();
3538
private final Map<String, Map<String, String>> namedImports = new TreeMap<>();
@@ -38,6 +41,7 @@ final class ImportDeclarations {
3841
if (!relativize.startsWith("./")) {
3942
relativize = "./" + relativize;
4043
}
44+
this.moduleNameString = relativize;
4145

4246
// Strip off the filename of what's being relativized since it isn't needed.
4347
this.relativize = Paths.get(relativize).getParent();
@@ -75,6 +79,13 @@ ImportDeclarations addImport(String name, String alias, String module) {
7579
return this;
7680
}
7781

82+
@Override
83+
public void importSymbol(Symbol symbol, String alias) {
84+
if (!symbol.getNamespace().isEmpty() && !symbol.getNamespace().equals(moduleNameString)) {
85+
addImport(symbol.getName(), alias, symbol.getNamespace());
86+
}
87+
}
88+
7889
@Override
7990
public String toString() {
8091
StringBuilder result = new StringBuilder();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/*
2+
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.smithy.typescript.codegen;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
import software.amazon.smithy.build.FileManifest;
21+
import software.amazon.smithy.codegen.core.CodegenContext;
22+
import software.amazon.smithy.codegen.core.SymbolProvider;
23+
import software.amazon.smithy.model.Model;
24+
import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator;
25+
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
26+
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
27+
import software.amazon.smithy.utils.SmithyBuilder;
28+
import software.amazon.smithy.utils.SmithyUnstableApi;
29+
30+
/**
31+
* Holds context related to code generation.
32+
*/
33+
@SmithyUnstableApi
34+
public final class TypeScriptCodegenContext
35+
implements CodegenContext<TypeScriptSettings, TypeScriptWriter, TypeScriptIntegration> {
36+
37+
private final Model model;
38+
private final TypeScriptSettings settings;
39+
private final SymbolProvider symbolProvider;
40+
private final FileManifest fileManifest;
41+
private final TypeScriptDelegator writerDelegator;
42+
private final List<TypeScriptIntegration> integrations;
43+
private final List<RuntimeClientPlugin> runtimePlugins;
44+
private final ProtocolGenerator protocolGenerator;
45+
private final ApplicationProtocol applicationProtocol;
46+
47+
private TypeScriptCodegenContext(Builder builder) {
48+
model = SmithyBuilder.requiredState("model", builder.model);
49+
settings = SmithyBuilder.requiredState("settings", builder.settings);
50+
symbolProvider = SmithyBuilder.requiredState("symbolProvider", builder.symbolProvider);
51+
fileManifest = SmithyBuilder.requiredState("fileManifest", builder.fileManifest);
52+
writerDelegator = SmithyBuilder.requiredState("writerDelegator", builder.writerDelegator);
53+
integrations = SmithyBuilder.requiredState("integrations", builder.integrations);
54+
runtimePlugins = SmithyBuilder.requiredState("runtimePlugins", builder.runtimePlugins);
55+
protocolGenerator = builder.protocolGenerator;
56+
applicationProtocol = SmithyBuilder.requiredState("applicationProtocol", builder.applicationProtocol);
57+
}
58+
59+
@Override
60+
public Model model() {
61+
return model;
62+
}
63+
64+
@Override
65+
public TypeScriptSettings settings() {
66+
return settings;
67+
}
68+
69+
@Override
70+
public SymbolProvider symbolProvider() {
71+
return symbolProvider;
72+
}
73+
74+
@Override
75+
public FileManifest fileManifest() {
76+
return fileManifest;
77+
}
78+
79+
@Override
80+
public TypeScriptDelegator writerDelegator() {
81+
return writerDelegator;
82+
}
83+
84+
@Override
85+
public List<TypeScriptIntegration> integrations() {
86+
return integrations;
87+
}
88+
89+
public List<RuntimeClientPlugin> runtimePlugins() {
90+
return runtimePlugins;
91+
}
92+
93+
public ProtocolGenerator protocolGenerator() {
94+
return protocolGenerator;
95+
}
96+
97+
public ApplicationProtocol applicationProtocol() {
98+
return applicationProtocol;
99+
}
100+
101+
/**
102+
* @return Returns a builder.
103+
*/
104+
public static Builder builder() {
105+
return new Builder();
106+
}
107+
108+
/**
109+
* Builds {@link TypeScriptCodegenContext}s.
110+
*/
111+
public static final class Builder implements SmithyBuilder<TypeScriptCodegenContext> {
112+
private Model model;
113+
private TypeScriptSettings settings;
114+
private SymbolProvider symbolProvider;
115+
private FileManifest fileManifest;
116+
private TypeScriptDelegator writerDelegator;
117+
private List<TypeScriptIntegration> integrations = new ArrayList<>();
118+
private List<RuntimeClientPlugin> runtimePlugins = new ArrayList<>();
119+
private ProtocolGenerator protocolGenerator;
120+
private ApplicationProtocol applicationProtocol;
121+
122+
@Override
123+
public TypeScriptCodegenContext build() {
124+
return new TypeScriptCodegenContext(this);
125+
}
126+
127+
/**
128+
* @param model The model being generated.
129+
* @return Returns the builder.
130+
*/
131+
public Builder model(Model model) {
132+
this.model = model;
133+
return this;
134+
}
135+
136+
/**
137+
* @param settings The resolved settings for the generator.
138+
* @return Returns the builder.
139+
*/
140+
public Builder settings(TypeScriptSettings settings) {
141+
this.settings = settings;
142+
return this;
143+
}
144+
145+
/**
146+
* @param symbolProvider The finalized symbol provider for the generator.
147+
* @return Returns the builder.
148+
*/
149+
public Builder symbolProvider(SymbolProvider symbolProvider) {
150+
this.symbolProvider = symbolProvider;
151+
return this;
152+
}
153+
154+
/**
155+
* @param fileManifest The file manifest being used in the generator.
156+
* @return Returns the builder.
157+
*/
158+
public Builder fileManifest(FileManifest fileManifest) {
159+
this.fileManifest = fileManifest;
160+
return this;
161+
}
162+
163+
/**
164+
* @param writerDelegator The writer delegator to use in the generator.
165+
* @return Returns the builder.
166+
*/
167+
public Builder writerDelegator(TypeScriptDelegator writerDelegator) {
168+
this.writerDelegator = writerDelegator;
169+
return this;
170+
}
171+
172+
/**
173+
* @param integrations The integrations to use in the generator.
174+
* @return Returns the builder.
175+
*/
176+
public Builder integrations(List<TypeScriptIntegration> integrations) {
177+
this.integrations.clear();
178+
this.integrations.addAll(integrations);
179+
return this;
180+
}
181+
182+
/**
183+
* @param runtimePlugins The runtime plugins to use in the generator.
184+
* @return Returns the builder.
185+
*/
186+
public Builder runtimePlugins(List<RuntimeClientPlugin> runtimePlugins) {
187+
this.runtimePlugins.clear();
188+
this.runtimePlugins.addAll(runtimePlugins);
189+
return this;
190+
}
191+
192+
/**
193+
* @param protocolGenerator The protocol generator to use in the generator.
194+
* @return Returns the builder.
195+
*/
196+
public Builder protocolGenerator(ProtocolGenerator protocolGenerator) {
197+
this.protocolGenerator = protocolGenerator;
198+
return this;
199+
}
200+
201+
/**
202+
* @param applicationProtocol The application protocol to use in the generator.
203+
* @return Returns the builder.
204+
*/
205+
public Builder applicationProtocol(ApplicationProtocol applicationProtocol) {
206+
this.applicationProtocol = applicationProtocol;
207+
return this;
208+
}
209+
}
210+
}

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptCodegenPlugin.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717

1818
import software.amazon.smithy.build.PluginContext;
1919
import software.amazon.smithy.build.SmithyBuildPlugin;
20-
import software.amazon.smithy.codegen.core.SymbolProvider;
21-
import software.amazon.smithy.model.Model;
22-
import software.amazon.smithy.typescript.codegen.TypeScriptSettings.ArtifactType;
20+
import software.amazon.smithy.codegen.core.directed.CodegenDirector;
21+
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
2322
import software.amazon.smithy.utils.SmithyInternalApi;
2423

2524
/**
@@ -35,11 +34,33 @@ public String getName() {
3534

3635
@Override
3736
public void execute(PluginContext context) {
38-
new CodegenVisitor(context, ArtifactType.CLIENT).execute();
39-
}
37+
CodegenDirector<TypeScriptWriter, TypeScriptIntegration, TypeScriptCodegenContext, TypeScriptSettings> runner
38+
= new CodegenDirector<>();
39+
40+
runner.directedCodegen(new DirectedTypeScriptCodegen());
41+
42+
// Set the SmithyIntegration class to look for and apply using SPI.
43+
runner.integrationClass(TypeScriptIntegration.class);
44+
45+
// Set the FileManifest and Model from the plugin.
46+
runner.fileManifest(context.getFileManifest());
47+
runner.model(context.getModel());
48+
49+
// Create the TypeScriptSettings object from the plugin settings.
50+
TypeScriptSettings settings = TypeScriptSettings.from(context.getModel(), context.getSettings(),
51+
TypeScriptSettings.ArtifactType.CLIENT);
52+
runner.settings(settings);
53+
54+
runner.service(settings.getService());
55+
56+
// Configure the director to perform some common model transforms.
57+
runner.performDefaultCodegenTransforms();
58+
59+
// TODO: Not using below because it would break existing AWS SDKs. Maybe it should be configurable
60+
// so generic SDKs call this by default, but AWS SDKs can opt-out of it via a setting.
61+
// runner.createDedicatedInputsAndOutputs();
4062

41-
@Deprecated
42-
public static SymbolProvider createSymbolProvider(Model model, TypeScriptSettings settings) {
43-
return new SymbolVisitor(model, settings);
63+
// Run it!
64+
runner.run();
4465
}
4566
}

0 commit comments

Comments
 (0)