Skip to content

Commit 425518c

Browse files
authored
support additional resolve function parameters (#302)
* support additional resolve function parameters Currently the generated client uses resolve functions to convert input symbol type to a resolved symbol type. It only take 1 input parameter which is the resolved symbol type returned from previous resolve function. In some cases, we need to supply more parameters to the resolve functions, like service client constructor, or specific command constructors. For example, to solve the circular dependency issue of STSClient -> credential providers -> STSClient, we need to supply the constructor of STSclient so the credential provider can work without circular dependency. This change allows users to generate additional parameters to the specific resolve function. Since the resolve function can only be generated within client constructor, the available parameters within the scope if steady. * address feedbacks * fix docs for RuntimeClientPlugin#additionalResolveFunctionParameters()
1 parent 590ebea commit 425518c

File tree

3 files changed

+90
-4
lines changed

3 files changed

+90
-4
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,15 @@ private void generateConstructor() {
291291
for (RuntimeClientPlugin plugin : runtimePlugins) {
292292
if (plugin.getResolveFunction().isPresent()) {
293293
configVariable++;
294-
writer.write("let $L = $T($L);",
294+
List<String> additionalParameters = plugin.getAdditionalResolveFunctionParameters();
295+
String additionalParamsString = additionalParameters.isEmpty()
296+
? ""
297+
: ", " + String.join(", ", additionalParameters);
298+
writer.write("let $L = $T($L$L);",
295299
generateConfigVariable(configVariable),
296300
plugin.getResolveFunction().get(),
297-
generateConfigVariable(configVariable - 1));
301+
generateConfigVariable(configVariable - 1),
302+
additionalParamsString);
298303
}
299304
}
300305

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/integration/RuntimeClientPlugin.java

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
package software.amazon.smithy.typescript.codegen.integration;
1717

18+
import java.util.ArrayList;
19+
import java.util.List;
1820
import java.util.Objects;
1921
import java.util.Optional;
2022
import java.util.Set;
@@ -26,6 +28,7 @@
2628
import software.amazon.smithy.model.shapes.OperationShape;
2729
import software.amazon.smithy.model.shapes.ServiceShape;
2830
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
31+
import software.amazon.smithy.utils.ListUtils;
2932
import software.amazon.smithy.utils.SmithyBuilder;
3033
import software.amazon.smithy.utils.StringUtils;
3134
import software.amazon.smithy.utils.ToSmithyBuilder;
@@ -44,6 +47,7 @@ public final class RuntimeClientPlugin implements ToSmithyBuilder<RuntimeClientP
4447
private final SymbolReference inputConfig;
4548
private final SymbolReference resolvedConfig;
4649
private final SymbolReference resolveFunction;
50+
private final List<String> additionalResolveFunctionParameters;
4751
private final SymbolReference pluginFunction;
4852
private final SymbolReference destroyFunction;
4953
private final BiPredicate<Model, ServiceShape> servicePredicate;
@@ -53,11 +57,16 @@ private RuntimeClientPlugin(Builder builder) {
5357
inputConfig = builder.inputConfig;
5458
resolvedConfig = builder.resolvedConfig;
5559
resolveFunction = builder.resolveFunction;
60+
additionalResolveFunctionParameters = ListUtils.copyOf(builder.additionalResolveFunctionParameters);
5661
pluginFunction = builder.pluginFunction;
5762
destroyFunction = builder.destroyFunction;
5863
operationPredicate = builder.operationPredicate;
5964
servicePredicate = builder.servicePredicate;
6065

66+
if (!additionalResolveFunctionParameters.isEmpty() && resolveFunction == null) {
67+
throw new IllegalStateException("Additional parameters can only be set if a resolve function is set.");
68+
}
69+
6170
boolean allNull = (inputConfig == null) && (resolvedConfig == null) && (resolveFunction == null);
6271
boolean allSet = (inputConfig != null) && (resolvedConfig != null) && (resolveFunction != null);
6372
if (!(allNull || allSet)) {
@@ -140,17 +149,32 @@ public Optional<SymbolReference> getResolvedConfig() {
140149
* <p>If the plugin has a resolve function, then it also must define a
141150
* <em>resolved interface</em> and a <em>resolve function</em>.
142151
* The referenced function must accept the input type of the plugin
143-
* as the first positional argument and return the resolved interface
144-
* as the return value.
152+
* as the first positional argument and optional parameters as additional
153+
* positional arguments, and return the resolved interface as the return
154+
* value.
145155
*
146156
* @return Returns the optionally present resolve function.
147157
* @see #getInputConfig()
158+
* @see #getAdditionalResolveFunctionParameters()
148159
* @see #getResolvedConfig()
149160
*/
150161
public Optional<SymbolReference> getResolveFunction() {
151162
return Optional.ofNullable(resolveFunction);
152163
}
153164

165+
/**
166+
* Gets a list of additional parameters to be supplied to the
167+
* resolve function. These parameters are to be supplied to resolve
168+
* function as Nth(N &gt; 1) positional arguments. The list is empty if
169+
* there are no additional parameters.
170+
*
171+
* @return Returns the optionally present list of parameters.
172+
* @see #getResolveFunction()
173+
*/
174+
public List<String> getAdditionalResolveFunctionParameters() {
175+
return additionalResolveFunctionParameters;
176+
}
177+
154178
/**
155179
* Gets the optionally present symbol reference that points to the
156180
* function that injects plugin middleware into the middleware stack
@@ -255,6 +279,7 @@ public String toString() {
255279
+ "inputConfig=" + inputConfig
256280
+ ", resolvedConfig=" + resolvedConfig
257281
+ ", resolveFunction=" + resolveFunction
282+
+ ", additionalResolveFunctionParameters=" + additionalResolveFunctionParameters
258283
+ ", pluginFunction=" + pluginFunction
259284
+ ", destroyFunction=" + destroyFunction
260285
+ '}';
@@ -272,6 +297,7 @@ public boolean equals(Object o) {
272297
return Objects.equals(inputConfig, that.inputConfig)
273298
&& Objects.equals(resolvedConfig, that.resolvedConfig)
274299
&& Objects.equals(resolveFunction, that.resolveFunction)
300+
&& Objects.equals(additionalResolveFunctionParameters, that.additionalResolveFunctionParameters)
275301
&& Objects.equals(pluginFunction, that.pluginFunction)
276302
&& Objects.equals(destroyFunction, that.destroyFunction)
277303
&& servicePredicate.equals(that.servicePredicate)
@@ -290,6 +316,7 @@ public static final class Builder implements SmithyBuilder<RuntimeClientPlugin>
290316
private SymbolReference inputConfig;
291317
private SymbolReference resolvedConfig;
292318
private SymbolReference resolveFunction;
319+
private List<String> additionalResolveFunctionParameters = new ArrayList<>();
293320
private SymbolReference pluginFunction;
294321
private SymbolReference destroyFunction;
295322
private BiPredicate<Model, ServiceShape> servicePredicate = (model, service) -> true;
@@ -374,6 +401,24 @@ public Builder resolveFunction(SymbolReference resolveFunction) {
374401
return this;
375402
}
376403

404+
/**
405+
* Sets the symbol reference that is invoked in order to convert the
406+
* input symbol type to a resolved symbol type.
407+
*
408+
* <p>If this is set, then both {@link #resolvedConfig} and
409+
* {@link #inputConfig} must also be set.
410+
*
411+
* @param resolveFunction Function used to convert input to resolved.
412+
* @param additionalParameters Additional parameters to be generated as resolve function input.
413+
* @return Returns the builder.
414+
* @see #getResolveFunction()
415+
*/
416+
public Builder resolveFunction(SymbolReference resolveFunction, String... additionalParameters) {
417+
this.resolveFunction = resolveFunction;
418+
this.additionalResolveFunctionParameters = ListUtils.of(additionalParameters);
419+
return this;
420+
}
421+
377422
/**
378423
* Sets the symbol that is invoked in order to convert the
379424
* input symbol type to a resolved symbol type.
@@ -389,6 +434,38 @@ public Builder resolveFunction(Symbol resolveFunction) {
389434
return resolveFunction(SymbolReference.builder().symbol(resolveFunction).build());
390435
}
391436

437+
/**
438+
* Sets the symbol that is invoked in order to convert the
439+
* input symbol type to a resolved symbol type.
440+
*
441+
* <p>If this is set, then both {@link #resolvedConfig} and
442+
* {@link #inputConfig} must also be set.
443+
*
444+
* @param resolveFunction Function used to convert input to resolved.
445+
* @param additionalParameters Additional parameters to be generated as resolve function input.
446+
* @return Returns the builder.
447+
* @see #getResolveFunction()
448+
*/
449+
public Builder resolveFunction(Symbol resolveFunction, String... additionalParameters) {
450+
return resolveFunction(SymbolReference.builder().symbol(resolveFunction).build(), additionalParameters);
451+
}
452+
453+
/**
454+
* Set additional positional input parameters to resolve function. Set
455+
* this with no arguments to remove the current parameters.
456+
*
457+
* <p>If this is set, then all of {@link #resolveFunction},
458+
* {@link #resolvedConfig} and {@link #inputConfig} must also be set.
459+
*
460+
* @param additionalParameters Additional parameters to be generated as resolve function input.
461+
* @return Returns the builder.
462+
* @see #getResolveFunction()
463+
*/
464+
public Builder additionalResolveFunctionParameters(String... additionalParameters) {
465+
this.additionalResolveFunctionParameters = ListUtils.of(additionalParameters);
466+
return this;
467+
}
468+
392469
/**
393470
* Sets a function symbol reference used to configure clients and
394471
* commands to use a specific middleware function.

smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/integration/RuntimeClientPluginTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import software.amazon.smithy.model.Model;
1010
import software.amazon.smithy.model.shapes.OperationShape;
1111
import software.amazon.smithy.model.shapes.ServiceShape;
12+
import software.amazon.smithy.utils.ListUtils;
1213

1314
public class RuntimeClientPluginTest {
1415
@Test
@@ -68,6 +69,7 @@ public void allowsConfigurableServicePredicate() {
6869
public void configuresWithDefaultConventions() {
6970
RuntimeClientPlugin plugin = RuntimeClientPlugin.builder()
7071
.withConventions("foo/baz", "1.0.0", "Foo")
72+
.additionalResolveFunctionParameters("this")
7173
.build();
7274

7375
assertThat(plugin.getInputConfig().get().getSymbol().getNamespace(), equalTo("foo/baz"));
@@ -79,6 +81,8 @@ public void configuresWithDefaultConventions() {
7981
assertThat(plugin.getResolveFunction().get().getSymbol().getNamespace(), equalTo("foo/baz"));
8082
assertThat(plugin.getResolveFunction().get().getSymbol().getName(), equalTo("resolveFooConfig"));
8183

84+
assertThat(plugin.getAdditionalResolveFunctionParameters(), equalTo(ListUtils.of("this")));
85+
8286
assertThat(plugin.getPluginFunction().get().getSymbol().getNamespace(), equalTo("foo/baz"));
8387
assertThat(plugin.getPluginFunction().get().getSymbol().getName(), equalTo("getFooPlugin"));
8488

0 commit comments

Comments
 (0)