Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: sparse struct serializer #1086

Merged
merged 5 commits into from
May 9, 2024
Merged

fix: sparse struct serializer #1086

merged 5 commits into from
May 9, 2024

Conversation

0marperez
Copy link
Contributor

@0marperez 0marperez commented May 1, 2024

Issue #

N/A

Description of changes

Fix rendering of sparse structure serializers

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@0marperez 0marperez added the no-changelog Indicates that a changelog entry isn't required for a pull request. Use sparingly. label May 1, 2024

This comment has been minimized.

1 similar comment

This comment has been minimized.

@0marperez 0marperez marked this pull request as ready for review May 1, 2024 18:47
@0marperez 0marperez requested a review from a team as a code owner May 1, 2024 18:47

This comment has been minimized.

1 similar comment

This comment has been minimized.

Comment on lines 291 to 294
when (isSparse) {
true -> writer.write("if ($elementName != null) $serializerFnName(#T($valueToSerializeName, ::$serializerTypeName)) else serializeNull()", RuntimeTypes.Serde.asSdkSerializable)
false -> writer.write("$serializerFnName(#T($valueToSerializeName, ::$serializerTypeName))", RuntimeTypes.Serde.asSdkSerializable)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simplification: Consider using writer.wrapBlockIf to handle isSparse like we do in other parts of this class

Copy link
Contributor

@ianbotsf ianbotsf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness: Needs unit tests

This comment has been minimized.

Copy link
Contributor

@ianbotsf ianbotsf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

when (isSparse) {
true -> {
writer.withBlock("$containerName$listMemberName.forEach { ($keyName, $valueName) ->", "}") {
writer.withBlock("if (value != null) {", "} else entry(key, null as String?)") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correctness: should value be $valueName and key be $keyName?

when (isSparse) {
true -> {
writer.withBlock("$containerName$listMemberName.forEach { ($keyName, $valueName) ->", "}") {
writer.withBlock("if (value != null) {", "} else entry(key, null as String?)") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here about keyName, valueName

Comment on lines 488 to 502
when (isSparse) {
true -> {
writer.withBlock("$containerName$listMemberName.forEach { ($keyName, $valueName) ->", "}") {
writer.withBlock("if (value != null) {", "} else entry(key, null as String?)") {
writer.write("entry($keyValue, $valueName.#T())", RuntimeTypes.Core.Text.Encoding.encodeBase64String)
}
}
}
false -> {
writer.write(
"$containerName$listMemberName.forEach { ($keyName, $valueName) -> entry($keyValue, $valueName.#T()) }",
RuntimeTypes.Core.Text.Encoding.encodeBase64String,
)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possible simplification using wrapBlockIf:

writer.withBlock("$containerName$listMemberName.forEach { ($keyName, $valueName) ->", "}") {
    writer.wrapBlockIf(isSparse, "if ($valueName != null) {", "} else entry($keyName, null as String?)") {
        writer.write("entry($keyValue, $valueName.#T())", RuntimeTypes.Core.Text.Encoding.encodeBase64String)
    } 
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good simplification but it would cause codegen changes to the serializers that are not sparse when not necessary

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not seeing the codegen change, unless you are you talking about the newline?

Non-sparse currently:

$containerName$#listMemberName.forEach { ($keyName, $valueName) -> entry($keyValue, $valueName.encodeBase64String()) }

Non-sparse with my suggestio:

$containerName$listMemberName.forEach { ($keyName, $valueName) ->
    entry($keyValue, $valueName.encodeBase64String())
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm talking about the new line

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, well if you think it's a good simplification, I don't think the newline makes much of a difference. Just a suggestion, up to you

when (isSparse) {
true -> {
writer.withBlock("$containerName$listMemberName.forEach { ($keyName, $valueName) ->", "}") {
writer.withBlock("if (value != null) {", "} else entry(key, null as String?)") {
Copy link
Contributor

@lauzadis lauzadis May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Here we are assuming the value will always be a string (null as String?), I think that works because serializers will handle a null entry of any type the same way?

Is there a way to make this use the correct value type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Here we are assuming the value will always be a string (null as String?), I think that works because serializers will handle a null entry of any type the same way?

Yes that's right, there should be a way to use the correct value type but it's not simple and the results would be the same

Copy link
Contributor Author

@0marperez 0marperez May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, actually that's only true for the JsonSerializer because of the XmlSerializer we need to use as String?

override fun entry(key: String, value: Int?): Unit = writeEntry(key) { xmlWriter.text(value.toString()) }
override fun entry(key: String, value: Long?): Unit = writeEntry(key) { xmlWriter.text(value.toString()) }
override fun entry(key: String, value: Float?): Unit = writeEntry(key) { xmlWriter.text(value.toString()) }
override fun entry(key: String, value: String?): Unit = writeEntry(key) { xmlWriter.text(value ?: "") }
override fun entry(key: String, value: SdkSerializable?): Unit = writeEntry(key) {
if (value == null) {
xmlWriter.text("")
return@writeEntry
}
xmlSerializer.parentDescriptorStack.push(descriptor)
value.serialize(xmlSerializer)
xmlSerializer.parentDescriptorStack.pop()
}
override fun entry(key: String, value: Double?): Unit = writeEntry(key) { xmlWriter.text(value.toString()) }
override fun entry(key: String, value: Boolean?): Unit = writeEntry(key) { xmlWriter.text(value.toString()) }
override fun entry(key: String, value: Byte?): Unit = writeEntry(key) { xmlWriter.text(value.toString()) }
override fun entry(key: String, value: Short?): Unit = writeEntry(key) { xmlWriter.text(value.toString()) }
override fun entry(key: String, value: Char?): Unit = writeEntry(key) { xmlWriter.text(value.toString()) }
override fun entry(key: String, value: Instant?, format: TimestampFormat): Unit = entry(key, value?.format(format))
override fun entry(key: String, value: Document?) =
throw SerializationException("document values not supported by xml serializer")

null.toString() returns the string "null" according to the docs

This comment has been minimized.

Copy link

github-actions bot commented May 9, 2024

Affected Artifacts

Significantly increased in size

Artifact Pull Request (bytes) Latest Release (bytes) Delta (bytes) Delta (percentage)
telemetry-api-jvm.jar 121,407 101,389 20,018 19.74%
aws-protocol-core-jvm.jar 24,042 22,705 1,337 5.89%
Changed in size
Artifact Pull Request (bytes) Latest Release (bytes) Delta (bytes) Delta (percentage)
runtime-core-jvm.jar 878,947 878,670 277 0.03%
http-client-jvm.jar 330,654 330,607 47 0.01%

@0marperez 0marperez merged commit 19cef35 into main May 9, 2024
15 checks passed
@0marperez 0marperez deleted the acmpca branch May 9, 2024 16:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
acknowledge-artifact-size-increase no-changelog Indicates that a changelog entry isn't required for a pull request. Use sparingly.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants