in codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/MemberCopierSpec.java [218:341]
private String copyMethodBody(CodeBlock.Builder code, BuilderTransform builderTransform, UniqueVariableSource variableSource,
EnumTransform enumTransform, String inputVariableName, MemberModel inputMember) {
if (inputMember.getEnumType() != null) {
String outputVariableName = variableSource.getNew("result");
ClassName enumType = poetExtensions.getModelClass(inputMember.getEnumType());
switch (enumTransform) {
case NONE:
return inputVariableName;
case ENUM_TO_STRING:
code.add("$T $N = $N.toString();", String.class, outputVariableName, inputVariableName);
return outputVariableName;
case STRING_TO_ENUM:
code.add("$1T $2N = $1T.fromValue($3N);", enumType, outputVariableName, inputVariableName);
return outputVariableName;
default:
throw new IllegalStateException();
}
}
if (inputMember.isSimple()) {
return inputVariableName;
}
if (inputMember.hasBuilder()) {
switch (builderTransform) {
case NONE:
return inputVariableName;
case BUILDER_TO_BUILDABLE:
String buildableOutput = variableSource.getNew("member");
TypeName buildableOutputType = typeName(inputMember, false, false, builderTransform, enumTransform);
code.add("$T $N = $N == null ? null : $N.build();", buildableOutputType, buildableOutput, inputVariableName,
inputVariableName);
return buildableOutput;
case BUILDABLE_TO_BUILDER:
String builderOutput = variableSource.getNew("member");
TypeName builderOutputType = typeName(inputMember, false, false, builderTransform, enumTransform);
code.add("$T $N = $N == null ? null : $N.toBuilder();", builderOutputType, builderOutput, inputVariableName,
inputVariableName);
return builderOutput;
default:
throw new IllegalStateException();
}
}
if (inputMember.isList()) {
String outputVariableName = variableSource.getNew("list");
String modifiableVariableName = variableSource.getNew("modifiableList");
MemberModel listEntryModel = inputMember.getListModel().getListMemberModel();
TypeName listType = typeName(inputMember, false, false, builderTransform, enumTransform);
code.add("$T $N;", listType, outputVariableName)
.add("if ($1N == null || $1N instanceof $2T) {", inputVariableName, SdkAutoConstructList.class)
.add("$N = $T.getInstance();", outputVariableName, DefaultSdkAutoConstructList.class)
.add("} else {");
String entryInputVariable = variableSource.getNew("entry");
// Short-circuit, if the member is simple then we can directly use the constructor
// that takes a collection which should have a better performance characteristics.
boolean isMemberSimple = listEntryModel.isSimple() && listEntryModel.getEnumType() == null;
if (isMemberSimple) {
code.add("$T $N = new $T<>($N);", listType, modifiableVariableName, ArrayList.class, inputVariableName);
} else {
code.add("$T $N = new $T<>($N.size());", listType, modifiableVariableName, ArrayList.class, inputVariableName);
code.add("$N.forEach($N -> {", inputVariableName, entryInputVariable);
String entryOutputVariable =
copyMethodBody(code, builderTransform, variableSource, enumTransform, entryInputVariable, listEntryModel);
code.add("$N.add($N);", modifiableVariableName, entryOutputVariable)
.add("});");
}
code.add("$N = $T.unmodifiableList($N);", outputVariableName, Collections.class, modifiableVariableName)
.add("}");
return outputVariableName;
}
if (inputMember.isMap()) {
String outputVariableName = variableSource.getNew("map");
String modifiableVariableName = variableSource.getNew("modifiableMap");
MemberModel keyModel = inputMember.getMapModel().getKeyModel();
MemberModel valueModel = inputMember.getMapModel().getValueModel();
TypeName keyType = typeName(keyModel, false, false, builderTransform, enumTransform);
TypeName outputMapType = typeName(inputMember, false, false, builderTransform, enumTransform);
code.add("$T $N;", outputMapType, outputVariableName)
.add("if ($1N == null || $1N instanceof $2T) {", inputVariableName, SdkAutoConstructMap.class)
.add("$N = $T.getInstance();", outputVariableName, DefaultSdkAutoConstructMap.class)
.add("} else {")
.add("$T $N = new $T<>($N.size());",
outputMapType, modifiableVariableName, LinkedHashMap.class, inputVariableName);
String keyInputVariable = variableSource.getNew("key");
String valueInputVariable = variableSource.getNew("value");
code.add("$N.forEach(($N, $N) -> {", inputVariableName, keyInputVariable, valueInputVariable);
String keyOutputVariable =
copyMethodBody(code, builderTransform, variableSource, enumTransform, keyInputVariable, keyModel);
String valueOutputVariable =
copyMethodBody(code, builderTransform, variableSource, enumTransform, valueInputVariable, valueModel);
if (keyModel.getEnumType() != null && !keyType.toString().equals("java.lang.String")) {
// When enums are used as keys, drop any entries with unknown keys
code.add("if ($N != $T.UNKNOWN_TO_SDK_VERSION) {", keyOutputVariable, keyType)
.add("$N.put($N, $N);", modifiableVariableName, keyOutputVariable, valueOutputVariable)
.add("}");
} else {
code.add("$N.put($N, $N);", modifiableVariableName, keyOutputVariable, valueOutputVariable);
}
code.add("});")
.add("$N = $T.unmodifiableMap($N);", outputVariableName, Collections.class, modifiableVariableName)
.add("}");
return outputVariableName;
}
throw new UnsupportedOperationException("Unable to generate copier for member '" + inputMember + "'");
}