in smithy-crt/src/main/kotlin/software/amazon/smithy/crt/java/JavaElements.kt [492:589]
fun build() : Builder<T> {
if (client.superclass != null && client.superclass!!.packageName() != "java.lang") {
builderInterface.addInterface(Interface(client.superclass!!.nestedClass("Builder")))
builderImpl.superclass(client.superclass!!.nestedClass("BuilderImpl"))
}
builderImpl.addDefaultConstructor().addModifier(Modifier.PROTECTED)
// private $Client(BuilderImpl builder)
client.addConstructor(Constructor(client.className, Field("builder", builderImpl.className))
.addModifier(Modifier.PROTECTED)
.java { builder ->
if (client.superclass != null && client.superclass!!.packageName() != "java.lang") {
builder.addStatement("super(builder)")
}
client.members.values.forEach { member ->
builder.addStatement("this.${'$'}L = builder.${'$'}L",
StringUtils.uncapitalize(member.name), StringUtils.uncapitalize(member.name))
}
}
)
// public Builder toBuilder()
val toBuilder = Method("toBuilder", builderInterface.className)
.addModifier(Modifier.PUBLIC)
.java { builder ->
builder.addStatement("return new ${'$'}T(this)", builderImpl.className)
}
if (client.superclass != null && client.superclass!!.packageName() != "java.lang") {
toBuilder.addAnnotation(Annotation(ClassName.get(Override::class.javaObjectType)))
}
client.addMethod(toBuilder)
// public static Builder builder()
client.addMethod(Method("builder", builderInterface.className)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.java { builder ->
builder.addStatement("return new ${'$'}T()", builderImpl.className)
}
)
// public Builder $member(T $member)
client.members.values.forEach { member ->
builderInterface.addMethod(
Method(
StringUtils.uncapitalize(member.name),
builderInterface.className,
Field(StringUtils.uncapitalize(member.name), member.typeName)
).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
)
}
builderInterface.addMethod(
Method(
"build",
client.className
).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
)
builderImpl
.addConstructor(Constructor(client.className, Field("model", client.className))
.addModifier(Modifier.PRIVATE)
.java { builder ->
client.members.values.forEach { member ->
builder.addStatement("${'$'}L(model.${'$'}L)",
StringUtils.uncapitalize(member.name), StringUtils.uncapitalize(member.name))
}
}
)
.addMethod(Method("build", client.className)
.addModifier(Modifier.PUBLIC)
.java { builder ->
builder.addStatement("return new ${'$'}T(this)", client.className)
}
)
client.members.values.forEach { member ->
builderImpl.addMethod(
Method(
StringUtils.uncapitalize(member.name),
builderInterface.className,
Field(StringUtils.uncapitalize(member.name), member.typeName)
).addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.java {
it.addStatement("this.${'$'}L = ${'$'}L",
StringUtils.uncapitalize(member.name), StringUtils.uncapitalize(member.name))
it.addStatement("return this")
}
)
builderImpl.addMember(member)
}
val builder = client.java() as TypeSpec.Builder
builder.addType(builderInterface.build().java().build())
builder.addType(builderImpl.build().java().build())
return this
}