diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java index bb473993035b..53311acc10b6 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java @@ -377,33 +377,56 @@ private boolean returnTypeIs(Class clazz) { } public String getFluentSetterDocumentation() { - StringBuilder docBuilder = new StringBuilder(); - docBuilder.append(getSetterDocumentation()) - .append(LF) - .append("@return " + stripHtmlTags(DEFAULT_FLUENT_RETURN)) - .append(getEnumDoc()); - return docBuilder.toString(); + return getSetterDocumentation() + + LF + + "@return " + stripHtmlTags(DEFAULT_FLUENT_RETURN) + + getEnumDoc(); + } + + public String getDefaultConsumerFluentSetterDocumentation() { + return (StringUtils.isNotBlank(documentation) ? documentation : DEFAULT_SETTER.replace("%s", name) + "\n") + + LF + + "This is a convenience that creates an instance of the {@link " + + variable.getSimpleType() + + ".Builder} avoiding the need to create one manually via {@link " + + variable.getSimpleType() + + "#builder()}.\n" + + LF + + "When the {@link Consumer} completes, {@link " + + variable.getSimpleType() + + ".Builder#build()} is called immediately and its result is passed to {@link #" + + getFluentGetterMethodName() + + "(" + + variable.getSimpleType() + + ")}." + + LF + + "@param " + + variable.getVariableName() + + " a consumer that will call methods on {@link " + + variable.getSimpleType() + ".Builder}" + + LF + + "@return " + stripHtmlTags(DEFAULT_FLUENT_RETURN) + + LF + + "@see #" + + getFluentSetterMethodName() + + "(" + + variable.getSimpleType() + + ")"; } private String getParamDoc() { - StringBuilder docBuilder = new StringBuilder(); - - String variableDesc = StringUtils.isNotBlank(documentation) ? documentation : DEFAULT_SETTER_PARAM.replace("%s", name); - - docBuilder.append(LF) - .append("@param ") - .append(variable.getVariableName()) - .append(" ") - .append(stripHtmlTags(variableDesc)); - return docBuilder.toString(); + return LF + + "@param " + + variable.getVariableName() + + " " + + stripHtmlTags(StringUtils.isNotBlank(documentation) ? documentation : DEFAULT_SETTER_PARAM.replace("%s", name)); } private String getEnumDoc() { StringBuilder docBuilder = new StringBuilder(); if (enumType != null) { - docBuilder.append(LF); - docBuilder.append("@see " + enumType); + docBuilder.append(LF).append("@see ").append(enumType); } return docBuilder.toString(); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/AbstractMemberSetters.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/AbstractMemberSetters.java index e53e18cf2eb1..9581d64c9632 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/AbstractMemberSetters.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/AbstractMemberSetters.java @@ -54,11 +54,12 @@ abstract class AbstractMemberSetters implements MemberSetters { this.poetExtensions = new PoetExtensions(intermediateModel); } - protected MethodSpec.Builder fluentSetterDeclaration(ParameterSpec parameter, TypeName returnType) { - return MethodSpec.methodBuilder(memberModel().getFluentSetterMethodName()) - .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) - .addParameter(parameter) - .returns(returnType); + protected MethodSpec.Builder fluentAbstractSetterDeclaration(ParameterSpec parameter, TypeName returnType) { + return fluentSetterDeclaration(parameter, returnType).addModifiers(Modifier.ABSTRACT); + } + + protected MethodSpec.Builder fluentDefaultSetterDeclaration(ParameterSpec parameter, TypeName returnType) { + return fluentSetterDeclaration(parameter, returnType).addModifiers(Modifier.DEFAULT); } protected MethodSpec.Builder fluentSetterBuilder(TypeName returnType) { @@ -142,6 +143,13 @@ protected boolean annotateJsonProperty() { return intermediateModel.getMetadata().isJsonProtocol() && shapeModel.getShapeType() == ShapeType.Exception; } + private MethodSpec.Builder fluentSetterDeclaration(ParameterSpec parameter, TypeName returnType) { + return MethodSpec.methodBuilder(memberModel().getFluentSetterMethodName()) + .addModifiers(Modifier.PUBLIC) + .addParameter(parameter) + .returns(returnType); + } + private CodeBlock copySetterBody(String copyAssignment, String regularAssignment, String copyMethodName) { Optional copierClass = serviceModelCopiers.copierClassFor(memberModel); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ListSetters.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ListSetters.java index eba63a861db8..77d399152f8a 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ListSetters.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ListSetters.java @@ -49,17 +49,17 @@ public List fluentDeclarations(TypeName returnType) { String setterDocumentation = memberModel().getFluentSetterDocumentation(); - fluentDeclarations.add(fluentSetterDeclaration(memberAsParameter(), returnType) + fluentDeclarations.add(fluentAbstractSetterDeclaration(memberAsParameter(), returnType) .addJavadoc("$L", setterDocumentation) .build()); - fluentDeclarations.add(fluentSetterDeclaration(ParameterSpec.builder(asArray(), fieldName()).build(), returnType) + fluentDeclarations.add(fluentAbstractSetterDeclaration(ParameterSpec.builder(asArray(), fieldName()).build(), returnType) .addJavadoc("$L", setterDocumentation) .varargs(true) .build()); if (memberModel().getEnumType() != null) { - fluentDeclarations.add(fluentSetterDeclaration(ParameterSpec.builder( + fluentDeclarations.add(fluentAbstractSetterDeclaration(ParameterSpec.builder( asArrayOfModeledEnum(), fieldName()).build(), returnType) .varargs(true) .addJavadoc("$L", setterDocumentation) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/MapSetters.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/MapSetters.java index 41c2592a584f..0d6e8489bf39 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/MapSetters.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/MapSetters.java @@ -32,7 +32,7 @@ class MapSetters extends AbstractMemberSetters { } public List fluentDeclarations(TypeName returnType) { - return Collections.singletonList(fluentSetterDeclaration(memberAsParameter(), returnType) + return Collections.singletonList(fluentAbstractSetterDeclaration(memberAsParameter(), returnType) .addJavadoc("$L", memberModel().getFluentSetterDocumentation()) .build()); } diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/NonCollectionSetters.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/NonCollectionSetters.java index 21c308d6c074..1ac4de4f3540 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/NonCollectionSetters.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/NonCollectionSetters.java @@ -17,12 +17,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; +import javax.lang.model.element.Modifier; import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.intermediate.MemberModel; import software.amazon.awssdk.codegen.model.intermediate.ShapeModel; @@ -37,14 +41,18 @@ class NonCollectionSetters extends AbstractMemberSetters { public List fluentDeclarations(TypeName returnType) { List fluentDeclarations = new ArrayList<>(); - fluentDeclarations.add(fluentSetterDeclaration(memberAsParameter(), returnType) - .addJavadoc("$L", memberModel().getFluentSetterDocumentation()) - .build()); + fluentDeclarations.add(fluentAbstractSetterDeclaration(memberAsParameter(), returnType) + .addJavadoc("$L", memberModel().getFluentSetterDocumentation()) + .build()); if (memberModel().getEnumType() != null) { - fluentDeclarations.add(fluentSetterDeclaration(modeledParam(), returnType) - .addJavadoc("$L", memberModel().getFluentSetterDocumentation()) - .build()); + fluentDeclarations.add(fluentAbstractSetterDeclaration(modeledParam(), returnType) + .addJavadoc("$L", memberModel().getFluentSetterDocumentation()) + .build()); + } + + if (memberModel().hasBuilder()) { + fluentDeclarations.add(fluentConsumerFluentSetter(returnType)); } return fluentDeclarations; @@ -79,23 +87,40 @@ public MethodSpec beanStyle() { private MethodSpec fluentAssignmentSetter(TypeName returnType) { return fluentSetterBuilder(returnType) - .addCode(copySetterBody().toBuilder().addStatement("return this").build()) - .build(); + .addCode(copySetterBody().toBuilder().addStatement("return this").build()) + .build(); } private MethodSpec fluentEnumToStringSetter(TypeName returnType) { return fluentSetterBuilder(modeledParam(), returnType) - .addCode(enumToStringAssignmentBody().toBuilder().addStatement("return this").build()) - .build(); + .addCode(enumToStringAssignmentBody().toBuilder().addStatement("return this").build()) + .build(); + } + + private MethodSpec fluentConsumerFluentSetter(TypeName returnType) { + ClassName memberClass = poetExtensions.getModelClass(memberModel().getShape().getC2jName()); + ClassName builderClass = memberClass.nestedClass("Builder"); + return fluentDefaultSetterDeclaration(builderConsumerParam(builderClass), returnType) + .addModifiers(Modifier.DEFAULT) + .addStatement("return $N($T.builder().apply($N).build())", + memberModel().getFluentSetterMethodName(), + memberClass, + fieldName()) + .addJavadoc("$L", memberModel().getDefaultConsumerFluentSetterDocumentation()) + .build(); } private CodeBlock enumToStringAssignmentBody() { return CodeBlock.builder() - .addStatement("this.$N($N.toString())", fieldName(), fieldName()) - .build(); + .addStatement("this.$N($N.toString())", fieldName(), fieldName()) + .build(); } private ParameterSpec modeledParam() { return ParameterSpec.builder(poetExtensions.getModelClass(memberModel().getShape().getShapeName()), fieldName()).build(); } + + private ParameterSpec builderConsumerParam(ClassName builderClass) { + return ParameterSpec.builder(ParameterizedTypeName.get(ClassName.get(Consumer.class), builderClass), fieldName()).build(); + } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/alltypesrequest.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/alltypesrequest.java index 3bffe8077116..1320d3cd5233 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/alltypesrequest.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/alltypesrequest.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Generated; @@ -450,7 +451,8 @@ public SubTypeOne polymorphicTypeWithoutSubTypes() { * Returns the value of the EnumType property for this object. *

* If the service returns an enum value that is not available in the current SDK version, {@link #enumType} will - * return {@link EnumType#UNKNOWN_TO_SDK_VERSION}. The raw value returned by the service is available from {@link #enumTypeString}. + * return {@link EnumType#UNKNOWN_TO_SDK_VERSION}. The raw value returned by the service is available from + * {@link #enumTypeString}. *

* * @return The value of the EnumType property for this object. @@ -464,7 +466,8 @@ public EnumType enumType() { * Returns the value of the EnumType property for this object. *

* If the service returns an enum value that is not available in the current SDK version, {@link #enumType} will - * return {@link EnumType#UNKNOWN_TO_SDK_VERSION}. The raw value returned by the service is available from {@link #enumTypeString}. + * return {@link EnumType#UNKNOWN_TO_SDK_VERSION}. The raw value returned by the service is available from + * {@link #enumTypeString}. *

* * @return The value of the EnumType property for this object. @@ -1063,6 +1066,24 @@ public interface Builder extends CopyableBuilder { */ Builder structWithNestedTimestampMember(StructWithTimestamp structWithNestedTimestampMember); + /** + * Sets the value of the StructWithNestedTimestampMember property for this object. + * + * This is a convenience that creates an instance of the {@link StructWithTimestamp.Builder} avoiding the need + * to create one manually via {@link StructWithTimestamp#builder()}. + * + * When the {@link Consumer} completes, {@link StructWithTimestamp.Builder#build()} is called immediately and + * its result is passed to {@link #structWithNestedTimestampMember(StructWithTimestamp)}. + * + * @param structWithNestedTimestampMember + * a consumer that will call methods on {@link StructWithTimestamp.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #structWithNestedTimestampMember(StructWithTimestamp) + */ + default Builder structWithNestedTimestampMember(Consumer structWithNestedTimestampMember) { + return structWithNestedTimestampMember(StructWithTimestamp.builder().apply(structWithNestedTimestampMember).build()); + } + /** * Sets the value of the BlobArg property for this object. *

@@ -1085,6 +1106,24 @@ public interface Builder extends CopyableBuilder { */ Builder structWithNestedBlob(StructWithNestedBlobType structWithNestedBlob); + /** + * Sets the value of the StructWithNestedBlob property for this object. + * + * This is a convenience that creates an instance of the {@link StructWithNestedBlobType.Builder} avoiding the + * need to create one manually via {@link StructWithNestedBlobType#builder()}. + * + * When the {@link Consumer} completes, {@link StructWithNestedBlobType.Builder#build()} is called immediately + * and its result is passed to {@link #structWithNestedBlob(StructWithNestedBlobType)}. + * + * @param structWithNestedBlob + * a consumer that will call methods on {@link StructWithNestedBlobType.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #structWithNestedBlob(StructWithNestedBlobType) + */ + default Builder structWithNestedBlob(Consumer structWithNestedBlob) { + return structWithNestedBlob(StructWithNestedBlobType.builder().apply(structWithNestedBlob).build()); + } + /** * Sets the value of the BlobMap property for this object. * @@ -1121,6 +1160,24 @@ public interface Builder extends CopyableBuilder { */ Builder recursiveStruct(RecursiveStructType recursiveStruct); + /** + * Sets the value of the RecursiveStruct property for this object. + * + * This is a convenience that creates an instance of the {@link RecursiveStructType.Builder} avoiding the need + * to create one manually via {@link RecursiveStructType#builder()}. + * + * When the {@link Consumer} completes, {@link RecursiveStructType.Builder#build()} is called immediately and + * its result is passed to {@link #recursiveStruct(RecursiveStructType)}. + * + * @param recursiveStruct + * a consumer that will call methods on {@link RecursiveStructType.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #recursiveStruct(RecursiveStructType) + */ + default Builder recursiveStruct(Consumer recursiveStruct) { + return recursiveStruct(RecursiveStructType.builder().apply(recursiveStruct).build()); + } + /** * Sets the value of the PolymorphicTypeWithSubTypes property for this object. * @@ -1130,6 +1187,24 @@ public interface Builder extends CopyableBuilder { */ Builder polymorphicTypeWithSubTypes(BaseType polymorphicTypeWithSubTypes); + /** + * Sets the value of the PolymorphicTypeWithSubTypes property for this object. + * + * This is a convenience that creates an instance of the {@link BaseType.Builder} avoiding the need to create + * one manually via {@link BaseType#builder()}. + * + * When the {@link Consumer} completes, {@link BaseType.Builder#build()} is called immediately and its result is + * passed to {@link #polymorphicTypeWithSubTypes(BaseType)}. + * + * @param polymorphicTypeWithSubTypes + * a consumer that will call methods on {@link BaseType.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #polymorphicTypeWithSubTypes(BaseType) + */ + default Builder polymorphicTypeWithSubTypes(Consumer polymorphicTypeWithSubTypes) { + return polymorphicTypeWithSubTypes(BaseType.builder().apply(polymorphicTypeWithSubTypes).build()); + } + /** * Sets the value of the PolymorphicTypeWithoutSubTypes property for this object. * @@ -1139,6 +1214,24 @@ public interface Builder extends CopyableBuilder { */ Builder polymorphicTypeWithoutSubTypes(SubTypeOne polymorphicTypeWithoutSubTypes); + /** + * Sets the value of the PolymorphicTypeWithoutSubTypes property for this object. + * + * This is a convenience that creates an instance of the {@link SubTypeOne.Builder} avoiding the need to create + * one manually via {@link SubTypeOne#builder()}. + * + * When the {@link Consumer} completes, {@link SubTypeOne.Builder#build()} is called immediately and its result + * is passed to {@link #polymorphicTypeWithoutSubTypes(SubTypeOne)}. + * + * @param polymorphicTypeWithoutSubTypes + * a consumer that will call methods on {@link SubTypeOne.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #polymorphicTypeWithoutSubTypes(SubTypeOne) + */ + default Builder polymorphicTypeWithoutSubTypes(Consumer polymorphicTypeWithoutSubTypes) { + return polymorphicTypeWithoutSubTypes(SubTypeOne.builder().apply(polymorphicTypeWithoutSubTypes).build()); + } + /** * Sets the value of the EnumType property for this object. * @@ -1545,7 +1638,7 @@ public final Builder structWithNestedTimestampMember(StructWithTimestamp structW public final void setStructWithNestedTimestampMember(StructWithTimestamp.BuilderImpl structWithNestedTimestampMember) { this.structWithNestedTimestampMember = structWithNestedTimestampMember != null ? structWithNestedTimestampMember - .build() : null; + .build() : null; } public final ByteBuffer getBlobArg() { diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/alltypesresponse.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/alltypesresponse.java index 9e49416923e7..9ed48d2eb913 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/alltypesresponse.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/alltypesresponse.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Generated; @@ -451,7 +452,8 @@ public SubTypeOne polymorphicTypeWithoutSubTypes() { * Returns the value of the EnumType property for this object. *

* If the service returns an enum value that is not available in the current SDK version, {@link #enumType} will - * return {@link EnumType#UNKNOWN_TO_SDK_VERSION}. The raw value returned by the service is available from {@link #enumTypeString}. + * return {@link EnumType#UNKNOWN_TO_SDK_VERSION}. The raw value returned by the service is available from + * {@link #enumTypeString}. *

* * @return The value of the EnumType property for this object. @@ -465,7 +467,8 @@ public EnumType enumType() { * Returns the value of the EnumType property for this object. *

* If the service returns an enum value that is not available in the current SDK version, {@link #enumType} will - * return {@link EnumType#UNKNOWN_TO_SDK_VERSION}. The raw value returned by the service is available from {@link #enumTypeString}. + * return {@link EnumType#UNKNOWN_TO_SDK_VERSION}. The raw value returned by the service is available from + * {@link #enumTypeString}. *

* * @return The value of the EnumType property for this object. @@ -1064,6 +1067,24 @@ public interface Builder extends CopyableBuilder { */ Builder structWithNestedTimestampMember(StructWithTimestamp structWithNestedTimestampMember); + /** + * Sets the value of the StructWithNestedTimestampMember property for this object. + * + * This is a convenience that creates an instance of the {@link StructWithTimestamp.Builder} avoiding the need + * to create one manually via {@link StructWithTimestamp#builder()}. + * + * When the {@link Consumer} completes, {@link StructWithTimestamp.Builder#build()} is called immediately and + * its result is passed to {@link #structWithNestedTimestampMember(StructWithTimestamp)}. + * + * @param structWithNestedTimestampMember + * a consumer that will call methods on {@link StructWithTimestamp.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #structWithNestedTimestampMember(StructWithTimestamp) + */ + default Builder structWithNestedTimestampMember(Consumer structWithNestedTimestampMember) { + return structWithNestedTimestampMember(StructWithTimestamp.builder().apply(structWithNestedTimestampMember).build()); + } + /** * Sets the value of the BlobArg property for this object. *

@@ -1086,6 +1107,24 @@ public interface Builder extends CopyableBuilder { */ Builder structWithNestedBlob(StructWithNestedBlobType structWithNestedBlob); + /** + * Sets the value of the StructWithNestedBlob property for this object. + * + * This is a convenience that creates an instance of the {@link StructWithNestedBlobType.Builder} avoiding the + * need to create one manually via {@link StructWithNestedBlobType#builder()}. + * + * When the {@link Consumer} completes, {@link StructWithNestedBlobType.Builder#build()} is called immediately + * and its result is passed to {@link #structWithNestedBlob(StructWithNestedBlobType)}. + * + * @param structWithNestedBlob + * a consumer that will call methods on {@link StructWithNestedBlobType.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #structWithNestedBlob(StructWithNestedBlobType) + */ + default Builder structWithNestedBlob(Consumer structWithNestedBlob) { + return structWithNestedBlob(StructWithNestedBlobType.builder().apply(structWithNestedBlob).build()); + } + /** * Sets the value of the BlobMap property for this object. * @@ -1122,6 +1161,24 @@ public interface Builder extends CopyableBuilder { */ Builder recursiveStruct(RecursiveStructType recursiveStruct); + /** + * Sets the value of the RecursiveStruct property for this object. + * + * This is a convenience that creates an instance of the {@link RecursiveStructType.Builder} avoiding the need + * to create one manually via {@link RecursiveStructType#builder()}. + * + * When the {@link Consumer} completes, {@link RecursiveStructType.Builder#build()} is called immediately and + * its result is passed to {@link #recursiveStruct(RecursiveStructType)}. + * + * @param recursiveStruct + * a consumer that will call methods on {@link RecursiveStructType.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #recursiveStruct(RecursiveStructType) + */ + default Builder recursiveStruct(Consumer recursiveStruct) { + return recursiveStruct(RecursiveStructType.builder().apply(recursiveStruct).build()); + } + /** * Sets the value of the PolymorphicTypeWithSubTypes property for this object. * @@ -1131,6 +1188,24 @@ public interface Builder extends CopyableBuilder { */ Builder polymorphicTypeWithSubTypes(BaseType polymorphicTypeWithSubTypes); + /** + * Sets the value of the PolymorphicTypeWithSubTypes property for this object. + * + * This is a convenience that creates an instance of the {@link BaseType.Builder} avoiding the need to create + * one manually via {@link BaseType#builder()}. + * + * When the {@link Consumer} completes, {@link BaseType.Builder#build()} is called immediately and its result is + * passed to {@link #polymorphicTypeWithSubTypes(BaseType)}. + * + * @param polymorphicTypeWithSubTypes + * a consumer that will call methods on {@link BaseType.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #polymorphicTypeWithSubTypes(BaseType) + */ + default Builder polymorphicTypeWithSubTypes(Consumer polymorphicTypeWithSubTypes) { + return polymorphicTypeWithSubTypes(BaseType.builder().apply(polymorphicTypeWithSubTypes).build()); + } + /** * Sets the value of the PolymorphicTypeWithoutSubTypes property for this object. * @@ -1140,6 +1215,24 @@ public interface Builder extends CopyableBuilder { */ Builder polymorphicTypeWithoutSubTypes(SubTypeOne polymorphicTypeWithoutSubTypes); + /** + * Sets the value of the PolymorphicTypeWithoutSubTypes property for this object. + * + * This is a convenience that creates an instance of the {@link SubTypeOne.Builder} avoiding the need to create + * one manually via {@link SubTypeOne#builder()}. + * + * When the {@link Consumer} completes, {@link SubTypeOne.Builder#build()} is called immediately and its result + * is passed to {@link #polymorphicTypeWithoutSubTypes(SubTypeOne)}. + * + * @param polymorphicTypeWithoutSubTypes + * a consumer that will call methods on {@link SubTypeOne.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #polymorphicTypeWithoutSubTypes(SubTypeOne) + */ + default Builder polymorphicTypeWithoutSubTypes(Consumer polymorphicTypeWithoutSubTypes) { + return polymorphicTypeWithoutSubTypes(SubTypeOne.builder().apply(polymorphicTypeWithoutSubTypes).build()); + } + /** * Sets the value of the EnumType property for this object. * @@ -1546,7 +1639,7 @@ public final Builder structWithNestedTimestampMember(StructWithTimestamp structW public final void setStructWithNestedTimestampMember(StructWithTimestamp.BuilderImpl structWithNestedTimestampMember) { this.structWithNestedTimestampMember = structWithNestedTimestampMember != null ? structWithNestedTimestampMember - .build() : null; + .build() : null; } public final ByteBuffer getBlobArg() { diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/recursivestructtype.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/recursivestructtype.java index 564c4993f529..f6ffd7dd76f8 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/recursivestructtype.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/recursivestructtype.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.Consumer; import java.util.stream.Collectors; import javax.annotation.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; @@ -162,16 +163,16 @@ public String toString() { public Optional getValueForField(String fieldName, Class clazz) { switch (fieldName) { - case "NoRecurse": - return Optional.of(clazz.cast(noRecurse())); - case "RecursiveStruct": - return Optional.of(clazz.cast(recursiveStruct())); - case "RecursiveList": - return Optional.of(clazz.cast(recursiveList())); - case "RecursiveMap": - return Optional.of(clazz.cast(recursiveMap())); - default: - return Optional.empty(); + case "NoRecurse": + return Optional.of(clazz.cast(noRecurse())); + case "RecursiveStruct": + return Optional.of(clazz.cast(recursiveStruct())); + case "RecursiveList": + return Optional.of(clazz.cast(recursiveList())); + case "RecursiveMap": + return Optional.of(clazz.cast(recursiveMap())); + default: + return Optional.empty(); } } @@ -200,6 +201,24 @@ public interface Builder extends CopyableBuilder { */ Builder recursiveStruct(RecursiveStructType recursiveStruct); + /** + * Sets the value of the RecursiveStruct property for this object. + * + * This is a convenience that creates an instance of the {@link RecursiveStructType.Builder} avoiding the need + * to create one manually via {@link RecursiveStructType#builder()}. + * + * When the {@link Consumer} completes, {@link RecursiveStructType.Builder#build()} is called immediately and + * its result is passed to {@link #recursiveStruct(RecursiveStructType)}. + * + * @param recursiveStruct + * a consumer that will call methods on {@link RecursiveStructType.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #recursiveStruct(RecursiveStructType) + */ + default Builder recursiveStruct(Consumer recursiveStruct) { + return recursiveStruct(RecursiveStructType.builder().apply(recursiveStruct).build()); + } + /** * Sets the value of the RecursiveList property for this object. *