Skip to content

Commit 815ebeb

Browse files
committed
fix: handle name collisions in codegen
1 parent 771b7c4 commit 815ebeb

23 files changed

Lines changed: 649 additions & 208 deletions

codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsAuthIntegration.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import static software.amazon.smithy.python.aws.codegen.AwsConfiguration.REGION;
88

99
import java.util.List;
10-
import java.util.Set;
1110
import software.amazon.smithy.aws.traits.auth.SigV4Trait;
1211
import software.amazon.smithy.codegen.core.Symbol;
1312
import software.amazon.smithy.model.shapes.ServiceShape;
@@ -16,6 +15,7 @@
1615
import software.amazon.smithy.python.codegen.CodegenUtils;
1716
import software.amazon.smithy.python.codegen.ConfigProperty;
1817
import software.amazon.smithy.python.codegen.GenerationContext;
18+
import software.amazon.smithy.python.codegen.RuntimeTypes;
1919
import software.amazon.smithy.python.codegen.SmithyPythonDependency;
2020
import software.amazon.smithy.python.codegen.integrations.AuthScheme;
2121
import software.amazon.smithy.python.codegen.integrations.PythonIntegration;
@@ -98,21 +98,22 @@ public void customize(GenerationContext context) {
9898
// must be accounted for.
9999
context.writerDelegator().useFileWriter(resolver.getDefinitionFile(), resolver.getNamespace(), writer -> {
100100
writer.addDependency(SmithyPythonDependency.SMITHY_HTTP);
101-
writer.addImport("smithy_core.interfaces.auth", "AuthOption", "AuthOptionProtocol");
102-
writer.addImports("smithy_core.auth", Set.of("AuthOption", "AuthParams"));
103-
writer.addImport("smithy_core.shapes", "ShapeID");
104101
writer.pushState();
105102

106103
writer.write("""
107-
def $1L(auth_params: AuthParams[Any, Any]) -> AuthOptionProtocol | None:
108-
return AuthOption(
109-
scheme_id=ShapeID($2S),
104+
def $1L(auth_params: $3T[Any, Any]) -> $4T | None:
105+
return $5T(
106+
scheme_id=$6T($2S),
110107
identity_properties={}, # type: ignore
111108
signer_properties={} # type: ignore
112109
)
113110
""",
114111
SIGV4_OPTION_GENERATOR_NAME,
115-
SigV4Trait.ID.toString());
112+
SigV4Trait.ID.toString(),
113+
RuntimeTypes.AUTH_PARAMS,
114+
RuntimeTypes.AUTH_OPTION_INTERFACE,
115+
RuntimeTypes.AUTH_OPTION,
116+
RuntimeTypes.SHAPE_ID);
116117
writer.popState();
117118
});
118119
}

codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsQueryProtocolGenerator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,11 @@ public ApplicationProtocol getApplicationProtocol(GenerationContext context) {
4747
@Override
4848
public void initializeProtocol(GenerationContext context, PythonWriter writer) {
4949
writer.addDependency(AwsPythonDependency.SMITHY_AWS_CORE.withOptionalDependencies("xml"));
50-
writer.addImport("smithy_aws_core.aio.protocols", "AwsQueryClientProtocol");
5150
var service = context.settings().service(context.model());
5251
var serviceSymbol = context.symbolProvider().toSymbol(service);
5352
var serviceSchema = serviceSymbol.expectProperty(SymbolProperties.SCHEMA);
5453
var version = service.getVersion();
55-
writer.write("AwsQueryClientProtocol($T, $S)", serviceSchema, version);
54+
writer.write("$1T($2T, $3S)", AwsRuntimeTypes.AWS_QUERY_CLIENT_PROTOCOL, serviceSchema, version);
5655
}
5756

5857
@Override
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package software.amazon.smithy.python.aws.codegen;
6+
7+
import software.amazon.smithy.codegen.core.Symbol;
8+
import software.amazon.smithy.utils.SmithyUnstableApi;
9+
10+
/**
11+
* Pre-defined Symbol constants for AWS-specific framework types used across generators.
12+
*
13+
* <p>Using these symbols with the {@code $T} formatter ensures that all framework type
14+
* references participate in the writer's collision detection system.
15+
*/
16+
@SmithyUnstableApi
17+
public final class AwsRuntimeTypes {
18+
19+
// smithy_aws_core.aio.protocols
20+
public static final Symbol REST_JSON_CLIENT_PROTOCOL = createSymbol(
21+
"aio.protocols",
22+
"RestJsonClientProtocol");
23+
public static final Symbol AWS_QUERY_CLIENT_PROTOCOL = createSymbol(
24+
"aio.protocols",
25+
"AwsQueryClientProtocol");
26+
27+
// smithy_aws_core.identity
28+
public static final Symbol STATIC_CREDENTIALS_RESOLVER = createSymbol(
29+
"identity",
30+
"StaticCredentialsResolver");
31+
32+
// smithy_aws_core.endpoints.standard_regional
33+
public static final Symbol STANDARD_REGIONAL_ENDPOINTS_RESOLVER = createSymbol(
34+
"endpoints.standard_regional",
35+
"StandardRegionalEndpointsResolver");
36+
37+
private AwsRuntimeTypes() {}
38+
39+
private static Symbol createSymbol(String module, String name) {
40+
var namespace = module.isEmpty() ? "smithy_aws_core" : "smithy_aws_core." + module;
41+
return Symbol.builder()
42+
.name(name)
43+
.namespace(namespace, ".")
44+
.addDependency(AwsPythonDependency.SMITHY_AWS_CORE)
45+
.build();
46+
}
47+
}

codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsStandardRegionalEndpointsIntegration.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,9 @@ public void write(PythonWriter writer, String previousText, InitDefaultEndpointR
5959
.map(ServiceTrait::getEndpointPrefix)
6060
.orElse(context.settings().service().getName());
6161

62-
writer.addImport("smithy_aws_core.endpoints.standard_regional",
63-
"StandardRegionalEndpointsResolver",
64-
"_RegionalResolver");
6562
writer.write(
66-
"self.endpoint_resolver = endpoint_resolver or _RegionalResolver(endpoint_prefix=$S)",
63+
"self.endpoint_resolver = endpoint_resolver or $1T(endpoint_prefix=$2S)",
64+
AwsRuntimeTypes.STANDARD_REGIONAL_ENDPOINTS_RESOLVER,
6765
endpointPrefix);
6866

6967
}

codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public void run() {
5050

5151
private void generateService(PythonWriter writer) {
5252
var serviceSymbol = symbolProvider.toSymbol(service);
53+
writer.addLocallyDefinedSymbol(serviceSymbol);
5354
var configSymbol = CodegenUtils.getConfigSymbol(context.settings());
5455
var pluginSymbol = CodegenUtils.getPluginSymbol(context.settings());
5556
writer.addLogger();
@@ -71,7 +72,6 @@ private void generateService(PythonWriter writer) {
7172
}
7273

7374
writer.addDependency(SmithyPythonDependency.SMITHY_CORE);
74-
writer.addImport("smithy_core.retries", "RetryStrategyResolver");
7575
writer.write("""
7676
def __init__(self, config: $1T | None = None, plugins: list[$2T] | None = None):
7777
$3C
@@ -86,12 +86,13 @@ def __init__(self, config: $1T | None = None, plugins: list[$2T] | None = None):
8686
for plugin in client_plugins:
8787
plugin(self._config)
8888
89-
self._retry_strategy_resolver = RetryStrategyResolver()
89+
self._retry_strategy_resolver = $5T()
9090
""",
9191
configSymbol,
9292
pluginSymbol,
9393
writer.consumer(w -> writeConstructorDocs(w, serviceSymbol.getName())),
94-
writer.consumer(w -> writeDefaultPlugins(w, defaultPlugins)));
94+
writer.consumer(w -> writeDefaultPlugins(w, defaultPlugins)),
95+
RuntimeTypes.RETRY_STRATEGY_RESOLVER);
9596

9697
var topDownIndex = TopDownIndex.of(model);
9798
var eventStreamIndex = EventStreamIndex.of(model);
@@ -209,46 +210,45 @@ private void writeSharedOperationInit(
209210
}
210211

211212
writer.putContext("operation", symbolProvider.toSymbol(operation));
212-
writer.addImport("smithy_core.aio.client", "ClientCall");
213-
writer.addImport("smithy_core.interceptors", "InterceptorChain");
214-
writer.addImport("smithy_core.types", "TypedProperties");
215-
writer.addImport("smithy_core.aio.client", "RequestPipeline");
216-
writer.addImport("smithy_core.exceptions", "ExpectationNotMetError");
217-
writer.addImport("smithy_core.retries", "RetryStrategyOptions");
218-
writer.addImport("smithy_core.interfaces.retries", "RetryStrategy");
219213
writer.addStdlibImport("copy", "deepcopy");
220214

221215
writer.write("""
222216
operation_plugins: list[Plugin] = [
223-
$C
217+
$1C
224218
]
225219
if plugins:
226220
operation_plugins.extend(plugins)
227221
config = deepcopy(self._config)
228222
for plugin in operation_plugins:
229223
plugin(config)
230224
if config.protocol is None or config.transport is None:
231-
raise ExpectationNotMetError("protocol and transport MUST be set on the config to make calls.")
225+
raise $2T("protocol and transport MUST be set on the config to make calls.")
232226
233227
retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy(
234228
retry_strategy=config.retry_strategy
235229
)
236230
237-
pipeline = RequestPipeline(
231+
pipeline = $3T(
238232
protocol=config.protocol,
239233
transport=config.transport
240234
)
241-
call = ClientCall(
235+
call = $4T(
242236
input=input,
243237
operation=${operation:T},
244-
context=TypedProperties({"config": config}),
245-
interceptor=InterceptorChain(config.interceptors),
238+
context=$5T({"config": config}),
239+
interceptor=$6T(config.interceptors),
246240
auth_scheme_resolver=config.auth_scheme_resolver,
247241
supported_auth_schemes=config.auth_schemes,
248242
endpoint_resolver=config.endpoint_resolver,
249243
retry_strategy=retry_strategy,
250244
)
251-
""", writer.consumer(w -> writeDefaultPlugins(w, defaultPlugins)));
245+
""",
246+
writer.consumer(w -> writeDefaultPlugins(w, defaultPlugins)),
247+
RuntimeTypes.EXPECTATION_NOT_MET_ERROR,
248+
RuntimeTypes.REQUEST_PIPELINE,
249+
RuntimeTypes.CLIENT_CALL,
250+
RuntimeTypes.TYPED_PROPERTIES,
251+
RuntimeTypes.INTERCEPTOR_CHAIN);
252252

253253
}
254254

@@ -291,14 +291,14 @@ private void generateEventStreamOperation(PythonWriter writer, OperationShape op
291291
// the type declaration so much that it's no better than Any.
292292
if (inputStreamSymbol.isPresent()) {
293293
if (outputStreamSymbol.isPresent()) {
294-
writer.addImport("smithy_core.aio.eventstream", "DuplexEventStream");
294+
writer.putContext("duplexEventStream", RuntimeTypes.DUPLEX_EVENT_STREAM);
295295
var outputDocs = "A `DuplexEventStream` for bidirectional streaming.";
296296
writer.write("""
297297
async def ${operationName:L}(
298298
self,
299299
input: ${input:T},
300300
plugins: list[${plugin:T}] | None = None
301-
) -> DuplexEventStream[${inputStream:T}, ${outputStream:T}, ${output:T}]:
301+
) -> ${duplexEventStream:T}[${inputStream:T}, ${outputStream:T}, ${output:T}]:
302302
${C|}
303303
return await pipeline.duplex_stream(
304304
call,
@@ -309,14 +309,14 @@ private void generateEventStreamOperation(PythonWriter writer, OperationShape op
309309
""",
310310
writer.consumer(w -> writeSharedOperationInit(w, operation, input, output, outputDocs)));
311311
} else {
312-
writer.addImport("smithy_core.aio.eventstream", "InputEventStream");
312+
writer.putContext("inputEventStream", RuntimeTypes.INPUT_EVENT_STREAM);
313313
var outputDocs = "An `InputEventStream` for client-to-server streaming.";
314314
writer.write("""
315315
async def ${operationName:L}(
316316
self,
317317
input: ${input:T},
318318
plugins: list[${plugin:T}] | None = None
319-
) -> InputEventStream[${inputStream:T}, ${output:T}]:
319+
) -> ${inputEventStream:T}[${inputStream:T}, ${output:T}]:
320320
${C|}
321321
return await pipeline.input_stream(
322322
call,
@@ -326,14 +326,14 @@ private void generateEventStreamOperation(PythonWriter writer, OperationShape op
326326
writer.consumer(w -> writeSharedOperationInit(w, operation, input, output, outputDocs)));
327327
}
328328
} else {
329-
writer.addImport("smithy_core.aio.eventstream", "OutputEventStream");
329+
writer.putContext("outputEventStream", RuntimeTypes.OUTPUT_EVENT_STREAM);
330330
var outputDocs = "An `OutputEventStream` for server-to-client streaming.";
331331
writer.write("""
332332
async def ${operationName:L}(
333333
self,
334334
input: ${input:T},
335335
plugins: list[${plugin:T}] | None = None
336-
) -> OutputEventStream[${outputStream:T}, ${output:T}]:
336+
) -> ${outputEventStream:T}[${outputStream:T}, ${output:T}]:
337337
${C|}
338338
return await pipeline.output_stream(
339339
call,

codegen/core/src/main/java/software/amazon/smithy/python/codegen/HttpAuthGenerator.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,22 @@ private void generateAuthSchemeResolver(
6969
.toList();
7070

7171
writer.pushState(new GenerateHttpAuthSchemeResolverSection(resolvedAuthSchemes));
72+
writer.addLocallyDefinedSymbol(resolverSymbol);
7273
writer.addDependency(SmithyPythonDependency.SMITHY_CORE);
7374
writer.addDependency(SmithyPythonDependency.SMITHY_HTTP);
74-
writer.addImport("smithy_core.interfaces.auth", "AuthOption", "AuthOptionProtocol");
75-
writer.addImport("smithy_core.auth", "AuthParams");
7675
writer.addStdlibImport("typing", "Any");
7776
writer.write("""
7877
class $1L:
79-
def resolve_auth_scheme(self, auth_parameters: AuthParams[Any, Any]) -> list[AuthOptionProtocol]:
80-
auth_options: list[AuthOptionProtocol] = []
78+
def resolve_auth_scheme(self, auth_parameters: $2T[Any, Any]) -> list[$3T]:
79+
auth_options: list[$3T] = []
8180
82-
${2C|}
83-
${3C|}
81+
${4C|}
82+
${5C|}
8483
8584
""",
8685
resolverSymbol.getName(),
86+
RuntimeTypes.AUTH_PARAMS,
87+
RuntimeTypes.AUTH_OPTION_INTERFACE,
8788
writer.consumer(w -> writeOperationAuthOptions(w, supportedAuthSchemes)),
8889
writer.consumer(w -> writeAuthOptions(w, resolvedAuthSchemes)));
8990
writer.popState();

0 commit comments

Comments
 (0)