Skip to content

Carry Java-only customizations as codegen traits in Smithy codegen - #7450

Merged
Fred1155 merged 2 commits into
feature/master/smithy-migrationfrom
bole/smithy_residual_customizations
Oct 19, 2026
Merged

Fred1155 merged 2 commits into
feature/master/smithy-migrationfrom
bole/smithy_residual_customizations

Conversation

@Fred1155

@Fred1155 Fred1155 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Motivation and Context

On the Smithy path, a service's customizations are applied as smithy-build transforms listed in its smithy-build.json. For example, a transform renames S3's CopyObjectRequest.Bucket member to DestinationBucket. Some customizations also have a part that only affects the generated Java and says nothing about the service. For example, S3 also keeps a deprecated bucket() accessor next to the new destinationBucket(), so existing callers still compile. Smithy has no standard trait for that.

This PR lets those Java-only settings travel through the model as traits, so the translator can read them from the member or shape they apply to. These are the settings, from customization.config shapeModifiers and customSdkShapes:

Setting What it does in the generated Java Used by
existingNameDeprecated Keeps deprecated accessors under a renamed member's old name s3, ssooidc
alternateBeanPropertyName Adds an extra bean-style setter dynamodb
ignoreDataTypeConversionFailures Unmarshalling ignores a value that does not convert to the member's type s3
emitEnumName Sets an enum constant's Java name cloudhsm
customSdkShapes Marks members that target an SDK-only shape as synthetic, so they are not marshalled s3

Modifications

addTraits transform (AddTraitsTransformer, registered with the other codegen transforms)

  • Adds traits to an existing shape or member.

Codegen traits (new, namespace software.amazon.awssdk.codegen)

Trait Applies to Sets in the intermediate model
deprecatedName (string) structure or union member the deprecated name and its getter and setter names
alternateBeanPropertyName (string) structure or union member an additional bean-style setter set<value>
ignoreDataTypeConversionFailures structure or union member the member's conversion-failure flag
enumConstantName (string) enum member the Java enum constant name
synthetic simple-type shape synthetic on members that target the shape
  • Defined in META-INF/smithy/aws-sdk-java-codegen-traits.smithy. Each trait's selector limits where it can be applied, and Smithy reports any other use as a validation error.
  • Each trait has a Java class in codegen/.../smithy/traits/, registered in META-INF/services/software.amazon.smithy.model.traits.TraitService. The classes are needed because the codegen transforms build traits with Smithy's TraitFactory, which rejects a trait ID with no registered class.

Translator

  • New SmithyCodegenTraits applies each trait to the intermediate model, setting the same fields as C2J's AddShapes: one method per member trait, and one that returns an enum constant's name.
  • AddSmithyShapes calls it once per trait when it builds a member, and in the loop that builds an enum's constants. Without the trait, a member or enum constant is built as before.

Postprocessor (SmithyIntermediateModelPostprocessor)

  • Adds MetadataModifiersProcessor, which copies customServiceMetadata.contentType from customization.config into the intermediate model metadata, as on the C2J path. Only Kinesis uses this in our repo. contentType applies to the whole service, so it stays in customization.config and does not become a trait.

Not in this PR

  • The tool that writes smithy-build.json from a service's customization.config comes in a follow-up PR, and it emits these traits. Until then nothing in the build adds them, so this PR changes no generated client.

Testing

  • AddTraitsTransformerTest: adds a member trait and replaces an existing one; adds a shape trait; fails on a missing shape and on an unknown trait.
  • SmithyCodegenTraitsTest: each trait ID creates its Java class; the trait definitions are found through discoverModels; a trait outside its selector is a validation error.
  • SmithyCodegenTraitsTranslationTest: each trait reaches the right intermediate-model field; deprecatedName on a list member fails, as on C2J; contentType reaches the metadata.
  • SmithyBuildTransformsTest.codegenTraits_reachTheIntermediateModel: traits added through a real smithy-build run reach the intermediate model.
  • SmithyIntermediateModelPostprocessorTest.javaOnlyShapeModifiersInConfigWithoutTraits_leaveTheModelUnchanged: the Smithy path no longer reads these settings from customization.config.

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the CONTRIBUTING document
  • Local run of mvn install succeeds
  • My code follows the code style of this project
  • My change requires a change to the Javadoc documentation
  • I have updated the Javadoc documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have added a changelog entry. Adding a new entry must be accomplished by running the scripts/new-change script and following the instructions. Commit the new file created by the script in .changes/next-release with your changes.
  • My change is to implement 1.11 parity feature and I have updated LaunchChangelog

License

  • I confirm that this pull request can be released under the Apache 2 license

@Fred1155
Fred1155 requested a review from a team as a code owner October 15, 2026 20:10
@alextwoods
alextwoods self-requested a review October 15, 2026 20:19
Comment thread codegen/src/main/resources/META-INF/smithy/aws-sdk-java-codegen-traits.smithy Outdated
Comment thread codegen/src/main/resources/META-INF/smithy/aws-sdk-java-codegen-traits.smithy Outdated

public static SmithyIntermediateModelPostprocessor create(CustomizationConfig config) {
List<CodegenCustomizationProcessor> processors = new ArrayList<>();
processors.add(new MetadataModifiersProcessor(config.getCustomServiceMetadata()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think there might be a small gap here. MetadataModifiersProcessor has two halves. postprocess applies contentType (now wired up). preprocess applies customServiceMetadata.protocol by overwriting ServiceMetadata.protocols — and this chain only ever calls postprocess, so on the Smithy path protocol is silently ignored. The only user in our services of protocol is Kinesis - but could potentially impact custom internal services....

I'd lean towards a fail fast check: throw in SmithyIntermediateModelPostprocessor.create when customServiceMetadata.protocol is non-null on the Smithy path (with a message pointing at addTraits + protocol traits which are the correct (and now supported) smithy way to handle this).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For this one, I have another PR #7442 to apply this preprocessing just for kinesis. And the old CBOR protocol has no Smithy trait..

@Fred1155
Fred1155 requested a review from alextwoods October 19, 2026 14:46
@Fred1155
Fred1155 merged commit 69bb469 into feature/master/smithy-migration Oct 19, 2026
3 of 4 checks passed
@Fred1155
Fred1155 deleted the bole/smithy_residual_customizations branch October 19, 2026 15:51
@github-actions

Copy link
Copy Markdown

This pull request has been closed and the conversation has been locked. Comments on closed PRs are hard for our team to see. If you need more assistance, please open a new issue that references this one.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Oct 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants