Skip to content
Merged
Show file tree
Hide file tree
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
Expand Up @@ -191,7 +191,11 @@ public MethodSpec recordAccountIdEndpointModeMethod() {
+ ".ifPresent(m -> executionAttributes.getAttribute($T.BUSINESS_METRICS).addMetric(m))",
BusinessMetricsUtils.class, SdkInternalExecutionAttribute.class);

builder.addStatement("return mode.name().toLowerCase()");
// Use value() rather than name().toLowerCase() so that the returned String is an interned compile-time
// literal. That keeps the reference stable across calls and removes a per-request allocation. It also
// avoids name().toLowerCase()'s dependence on the default locale, which mangles the value under a
// Turkish locale.
builder.addStatement("return mode.value()");

return builder.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,22 @@
import com.fasterxml.jackson.jr.stree.JrsString;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeVariableName;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
Expand Down Expand Up @@ -119,6 +123,7 @@ public TypeSpec poetSpec() {

b.addMethod(setStaticContextParamsMethod());
addStaticContextParamMethods(b);
addStaticListFields(b);

b.addMethod(authSchemeWithEndpointSignerPropertiesMethod());

Expand Down Expand Up @@ -342,9 +347,8 @@ private MethodSpec addStaticContextParamsMethod(OperationModel opModel) {
b.addStatement("params.$N($L)", setterName, ((JrsBoolean) value).booleanValue());
break;
case START_ARRAY:
JrsArray arrayValue = (JrsArray) value;
CodeBlock arrayCode = endpointRulesSpecUtils.treeNodeToLiteral(arrayValue);
b.addStatement("params.$N($L)", setterName, arrayCode);
String fieldName = staticListFieldName(opModel, n);
b.addStatement("params.$N($N)", setterName, fieldName);
break;
default:
throw new RuntimeException("Don't know how to set parameter of type " + value.asToken());
Expand All @@ -358,6 +362,57 @@ private String staticContextParamsMethodName(OperationModel opModel) {
return opModel.getMethodName() + "StaticContextParams";
}

/**
* Generates the name of the {@code static final List<String>} field holding the static array value of
* {@code paramName} for {@code opModel}.
*
* <p>Format: {@code STATIC_LIST_{OPERATION}_{PARAM}}
*/
private static String staticListFieldName(OperationModel opModel, String paramName) {
return "STATIC_LIST_" + screamCase(opModel.getOperationName()) + "_" + screamCase(paramName);
}

private static String screamCase(String word) {
return Stream.of(CodegenNamingUtils.splitOnWordBoundaries(word))
.map(s -> s.toUpperCase(Locale.US))
.collect(Collectors.joining("_"));
}

/**
* Generates a {@code private static final List<String>} field for every {@code staticContextParams} entry whose
* value is an array, so that {@code setStaticContextParams} hands the same list reference to the endpoint params
* builder on every call rather than constructing a new list each time.
*/
private void addStaticListFields(TypeSpec.Builder classBuilder) {
ParameterizedTypeName listOfString = ParameterizedTypeName.get(List.class, String.class);

model.getOperations().forEach((opName, opModel) -> {
Map<String, StaticContextParam> statics = opModel.getStaticContextParams();
if (CollectionUtils.isNullOrEmpty(statics)) {
return;
}
statics.forEach((paramName, scp) -> {
TreeNode value = scp.getValue();
if (value.asToken() != JsonToken.START_ARRAY) {
return;
}
JrsArray arrayValue = (JrsArray) value;
CodeBlock initializer;
if (arrayValue.size() == 0) {
initializer = CodeBlock.of("$T.emptyList()", Collections.class);
} else {
initializer = CodeBlock.of("$T.unmodifiableList($L)", Collections.class,
endpointRulesSpecUtils.treeNodeToLiteral(arrayValue));
}
FieldSpec field = FieldSpec.builder(listOfString, staticListFieldName(opModel, paramName),
Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer(initializer)
.build();
classBuilder.addField(field);
});
});
}

private boolean hasStaticContextParams(OperationModel opModel) {
Map<String, StaticContextParam> staticContextParams = opModel.getStaticContextParams();
return staticContextParams != null && !staticContextParams.isEmpty();
Expand Down
Loading
Loading