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

Improve IDL 1 and 2 interoperability #1394

Merged
merged 2 commits into from
Sep 11, 2022
Merged

Conversation

mtdowling
Copy link
Member

@mtdowling mtdowling commented Sep 9, 2022

This commit makes several significant updates to Smithy IDL 2 that
improve lossless interoperability with Smithy IDL 1:

  • Default traits can now coexist with required. This indicates that
    a member should be serialized, but it is a protocol-specific
    decision if and how this is enforced. This was a pattern that occurred
    in Smithy 1.0 models when a member was required and targeted a shape
    with a zero value.
  • Default traits can be added to root-level shapes. Any structure member
    that targets a shape marked with the default trait must repeat the
    default on the member. This removes the action at a distance problem
    observed in Smithy IDL 1 where a root level shape implicitly introduced
    a default zero value, and to know if that's the case for any member, you
    had to look through from the member to the target shape. This change
    allows us to know if a root level shape was boxed in IDL 1.0 too -- if
    it is a shape that had a zero value in IDL 1 and either doesn't have
    a default or the default is not the zero value, then it was boxed in v1.
  • When loading v2 models, we will now patch synthetic box traits onto shapes
    that would have been considered boxed by existing smithy-model consumers.
    This improves further interop with tooling that has not yet adopted
    Smithy IDL 2 or that hasn't yet migrated to use the NullableIndex
    abstraction.
  • Added an optional nullability report to smithy-build that shows the
    computed nullability semantics of each member in a model. This can be
    used to better understand nullability semantics.
  • Updated smithy-diff to not emit events when diffing a 1.0 model against
    the 2.0 serialized version of the model. This means that changes to the
    box trait are ignored unless the change impacts the nullability of the
    shape. Special handling was added to detect breaking changes with the
    default trait too (you can't change a default value of a root-level shape
    for example, you can't change a default value of a shape to or from the
    zero value of a type as this might break code generators, etc).
  • Add new NullableIndex modes for testing if a member is nullable based on
    the supported features of the generator. For example, some generators only
    make members non-optional when the member is set to the zero value of a
    type, so there is a NullableIndex check mode for that and other use cases.
  • Added the @addedDefault trait which is used to indicate that a @default
    trait was added to a member after it was initially released. This can be
    used by tooling to make an appropriate determination if generating a
    non-nullable type for the member is a backward compatible change. For
    example, if a generator only uses default zero values to generate
    non-nullable types, then the removal of the required trait and addition
    of a default trait would be a breaking change for them, so they can use
    addedDefault to ignore the default trait.
  • When loading 1.0 models, rather than dropping the default trait from a
    member when the range trait of a shape is invalid for its zero value, we
    now instead emit only a warning for this specific case. This prevents
    changing the type and also doesn't lose the range constraint in case
    implementations are relying on this validation.
  • Un-deprecated Primitive* shapes in the prelude and add the @default
    trait to them. Any member that targets one of these primitive prelude
    shapes must now also repeat the zero value of the target shape.
  • Fixed an issue where synthetic box traits were being dropped when the
    same model is loaded multiple times.

@mtdowling mtdowling force-pushed the model-evolution-updates branch 3 times, most recently from 304eb3b to 4abd94c Compare September 9, 2022 21:48
This commit makes several significant updates to Smithy IDL 2 that
improve lossless interoperability with Smithy IDL 1:

* Default traits can now coexist with required. This indicates that
  a member should be serialized, but it is a protocol-specific
  decision if and how this is enforced. This was a pattern that occurred
  in Smithy 1.0 models when a member was required and targeted a shape
  with a zero value.
* Default traits can be added to root-level shapes. Any structure member
  that targets a shape marked with the default trait must repeat the
  default on the member. This removes the action at a distance problem
  observed in Smithy IDL 1 where a root level shape implicitly introduced
  a default zero value, and to know if that's the case for any member, you
  had to look through from the member to the target shape. This change
  allows us to know if a root level shape was boxed in IDL 1.0 too -- if
  it is a shape that had a zero value in IDL 1 and either doesn't have
  a default or the default is not the zero value, then it was boxed in v1.
* When loading v2 models, we will now patch synthetic box traits onto shapes
  that would have been considered boxed by existing smithy-model consumers.
  This improves further interop with tooling that has not yet adopted
  Smithy IDL 2 or that hasn't yet migrated to use the NullableIndex
  abstraction.
* Added an optional nullability report to smithy-build that shows the
  computed nullability semantics of each member in a model. This can be
  used to better understand nullability semantics.
* Updated smithy-diff to not emit events when diffing a 1.0 model against
  the 2.0 serialized version of the model. This means that changes to the
  box trait are ignored unless the change impacts the nullability of the
  shape. Special handling was added to detect breaking changes with the
  default trait too (you can't change a default value of a root-level shape
  for example, you can't change a default value of a shape to or from the
  zero value of a type as this might break code generators, etc).
* Add new NullableIndex modes for testing if a member is nullable based on
  the supported features of the generator. For example, some generators only
  make members non-optional when the member is set to the zero value of a
  type, so there is a NullableIndex check mode for that and other use cases.
* Added the @addedDefault trait which is used to indicate that a `@default`
  trait was added to a member after it was initially released. This can be
  used by tooling to make an appropriate determination if generating a
  non-nullable type for the member is a backward compatible change. For
  example, if a generator only uses default zero values to generate
  non-nullable types, then the removal of the required trait and addition
  of a default trait would be a breaking change for them, so they can use
  addedDefault to ignore the default trait.
* When loading 1.0 models, rather than dropping the default trait from a
  member when the range trait of a shape is invalid for its zero value, we
  now instead emit only a warning for this specific case. This prevents
  changing the type and also doesn't lose the range constraint in case
  implementations are relying on this validation.
* Un-deprecated Primitive* shapes in the prelude and add the `@default`
  trait to them. Any member that targets one of these primitive prelude
  shapes must now also repeat the zero value of the target shape.
* Fixed an issue where synthetic box traits were being dropped when the
  same model is loaded multiple times.
@mtdowling mtdowling force-pushed the model-evolution-updates branch from 2391870 to 72e4b5a Compare September 10, 2022 22:53
Copy link
Contributor

@gosar gosar left a comment

Choose a reason for hiding this comment

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

All my comments are non-blocking, so marking Approved.

@mtdowling mtdowling force-pushed the model-evolution-updates branch from 798e8c4 to ac28bd2 Compare September 11, 2022 16:06
@mtdowling mtdowling merged commit 1f0da40 into main Sep 11, 2022
events.add(error(change.getNewShape(),
"@default trait was removed. This will break previously generated code."));
} else if (oldTrait == null) {
if (change.getNewShape().getType() != ShapeType.MEMBER) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: can also be changed to !change.getNewShape().isMemberShape()

@mtdowling mtdowling deleted the model-evolution-updates branch October 24, 2022 16:27
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.

2 participants