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

Multi-level discriminated models don't set their discriminators correctly #5156

Open
trrwilson opened this issue Nov 6, 2024 · 2 comments
Open
Labels
v3 Version 3 of AutoRest C# generator.

Comments

@trrwilson
Copy link
Member

trrwilson commented Nov 6, 2024

Problem summary

When defining a discriminated type that extends another discriminated type, the generated constructors for the downstream types don't set the right values, which results in malformed serialization.

Repro

Standalone project:
csharp-emitter-double-discriminator-repro.zip

Example models (from main.tsp):

@discriminator("taxonomic_family")
model Animal {
  taxonomic_family: string;
}

@discriminator("breed")
model Dog extends Animal {
  taxonomic_family: "canidae";
  breed: string;
}

model Labrador extends Dog {
  breed: "labrador";
}

With the above, the public Dog() constructor is an instance of the issue.

More details

From the README included in the above repro .zip:

npm install @azure-tools/typespec-csharp @autorest/csharp --save-dev
npx tsp compile .

Search for and open Dog.cs and observe the generated constructors:

        /// <summary> Initializes a new instance of <see cref="Dog"/>. </summary>
        public Dog()
        {
            Breed = "canidae";
        }

        /// <summary> Initializes a new instance of <see cref="Dog"/>. </summary>
        /// <param name="taxonomicFamily"></param>
        /// <param name="serializedAdditionalRawData"> Keeps track of any properties unknown to the library. </param>
        /// <param name="breed"></param>
        internal Dog(string taxonomicFamily, IDictionary<string, BinaryData> serializedAdditionalRawData, string breed) : base(taxonomicFamily, serializedAdditionalRawData)
        {
            Breed = breed;
        }

While the internal constructor is correct and properly sets the inner discriminator of Breed to the provided value while invoking the parent type's base constructor to set the outer discriminator of taxonomic_family, the public constructor has multiple issues:

  • It doesn't invoke the base constructor at all
  • It doesn't set the outer discriminator of taxonomic_value to any value
  • It instead sets the inner discriminator (breed) to the intended value of outer discriminator (taxonomic_family)

As a result of this, serialized instances of Dog are very malformed:

{
  "taxonomic_family": null,
  "breed": "canidae"
}
@trrwilson trrwilson added the v3 Version 3 of AutoRest C# generator. label Nov 6, 2024
@ArcturusZhang
Copy link
Member

ArcturusZhang commented Nov 7, 2024

@trrwilson :( unfortunately this is known issue for quite a long time.
Here is another issue tracking this: #5146

@JoshLove-msft do you know how and when we could deal with this? As far as I know, the new generator should be able to handle this case, right?

@JoshLove-msft
Copy link
Member

Yes, the new generator has support for multi-level discriminators.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v3 Version 3 of AutoRest C# generator.
Projects
None yet
Development

No branches or pull requests

3 participants