Use the original Node when creating traits #1047
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This commit updates traits to use the originally provided node value in a model file so that the value is persisted as-is when calling toNode on a trait.
We don't currently do a lot, if any, validation in trait node provider methods. We then explicitly take the parts out of traits that we want and ignore the rest of the node object. This results in use dropping additional properties on traits rather than warning about their presence, which makes it harder to know when a property has a typo. For example, see https://github.com/awslabs/smithy/blob/main/smithy-model/src/main/java/software/amazon/smithy/model/traits/HttpTrait.java#L50. Notice that no additional property validation is done on the trait. This is common across most traits.
By keeping the original node as-is, the TraitValueValidator can automatically detect additional properties.
In addition to validation, this change also removes the need to duplicate the work of creating node values for traits. For example, 412,359 fewer node values are created when loading all AWS models.
The tradeoff of this change is that if a trait does any kind of normalization of values or setting of defaults or if a trait has logic around omitting empty lists, false, etc, then traits may need to override
equals
andhashCode
since relying ontoNode
equality would render two traits inequal. That generally is fine, but it may be a problem if a model transformation is performed and you need to compare two models, you need to merge two models that might contain duplicate shapes as a result of a transform, etc.An alternative to this PR is to add things like
warnIfAdditionalProperties
to every trait provider that takes objects. A middleground could be reached too, where we keep the original node values for scalars and lists of scalars, but recompute and normalize the node values of traits that use object nodes.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.