Skip to content

Add Smithy intermediate model builder and mojo activation - #7279

Open
Fred1155 wants to merge 1 commit into
feature/master/smithy-migrationfrom
bole/add_smithy_im_builder
Open

Add Smithy intermediate model builder and mojo activation#7279
Fred1155 wants to merge 1 commit into
feature/master/smithy-migrationfrom
bole/add_smithy_im_builder

Conversation

@Fred1155

Copy link
Copy Markdown
Contributor

Motivation and Context

This builds an IntermediateModel from a Smithy model, and teaches the Maven mojo to use it when a model.json is present. It's a port of C2J's IntermediateModelBuilder.

The fastest way to review it is to open IntermediateModelBuilder next toSmithyIntermediateModelBuilder and work through the phase table below. Most of it is line-for-line. Four places needed real thought, and five C2J steps are missing on purpose.

Modifications

File Role C2J counterpart
smithy/SmithyIntermediateModelBuilder.java Smithy model → IntermediateModel IntermediateModelBuilder
smithy/SmithyModels.java input container C2jModels
maven/plugin/GenerationMojo.java route to Smithy when model.json present same file, C2J branch
codegen-maven-plugin/pom.xml declare smithy-model
RemoveUnusedShapes.java finalpublic final

There's no codegen/pom.xml change, because smithy-model, smithy-aws-traits andsmithy-rules-engine are already compile dependencies there. The plugin module did need smithy-model declared, since it now imports Model directly instead of picking it up transitively from codegen.

The only thing that reaches this builder is the mojo, and only for a model root that contains amodel.json. No shipped service has one, so generated output doesn't change.

Build phases

Phase C2J Here
Operations AddOperationsTreeMap AddSmithyOperationsTreeMap
Endpoint discovery find op, set endpointCacheRequired same (Will be changed in the follow up PR)
Shapes 6 processors 4 processors — D1
Deprecated operations removeIf same
First IntermediateModel full inputs paginators/waiters empty
Trim removeUnusedShapes + deprecated shapes same
Linking 5 calls same, 2 reimplemented — D3, D4

D1 — four shape processors where C2J has six. C2J runs AddEmptyInputShape and AddEmptyOutputShape as extra passes to invent request and response shapes for operations that declare none. The Smithy input and output processors do it inline, checking for smithy.api#Unit and calling synthesizeEmptyRequest or synthesizeEmptyResponse. Diffing the chains looks like a dropped step; the work just happens in one pass instead of two.

D2 — two linking methods read the built model instead of the raw one. C2J's versions reach back into its ServiceModel, which doesn't exist here. linkCustomAuthorizationToRequestShapes reads operation.getAuthType() off the OperationModel — the same value, since AddSmithyOperations.translateAuth sets it from the source C2J reads. linkOperationsToInputOutputShapes keys on smithy.api#Unit rather than C2J's getOutput() != null, which is how Smithy expresses "no output". The op != null guard beside it is unreachable.

D3 — clientContextParams is translated from smithy.rules#clientContextParams. This is the only behaviour the PR adds beyond wiring. It's not an internal field: it generates a public builder method per param, plus the key class and the endpoint-resolution wiring, so leaving it null silently removes public API rather than producing a subtly wrong model.

Two choices worth a look. It returns null rather than an empty map when the trait is absent, matching C2J, where an empty map would serialise as {} and read as a diff. And it sorts by name, because this map decides generated builder-method order and the trait's key order is arbitrary where C2J's happens to be alphabetical.

Set by C2J, not here

Five steps are missing on purpose. Taken together they're the main limit on what this builder can currently handle.

C2J step Here
customization.preprocess(service) nothing
customization.postprocess(fullModel) nothing
paginators.getPagination() Collections.emptyMap()
waiters.getWaiters() Collections.emptyMap()
customizeEndpointParameters, customizeOperationContextParams nothing

The endpoint rule set and endpoint tests still come from the sidecar JSON files, passed through SmithyModels untouched, even though the model carries @smithy.rules#endpointRuleSet and @smithy.rules#endpointTests inline.
following PR will prefer the trait and fall back to the sidecar.

Testing

Implemented parity fixture test, but not in this PR to keep it clean to review.

  • All 11 parity tests pass: 6 full-fidelity and 5 translation-only, covering ec2 (ec2Query), sqs (awsJson), route53 (rest-xml), sts (awsQuery) and kendraranking (rpcv2Cbor).
  • Translation-only mode empties customizations, paginators and waiters on both sides, so the comparison isolates pure translation.

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 August 14, 2026 20:43
@Fred1155
Fred1155 requested a review from RanVaknin August 14, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant