fix(openapi3): missing discriminator mapping entry when first union variant causes circular emit#10268
Open
jensdev wants to merge 1 commit intomicrosoft:mainfrom
Open
fix(openapi3): missing discriminator mapping entry when first union variant causes circular emit#10268jensdev wants to merge 1 commit intomicrosoft:mainfrom
jensdev wants to merge 1 commit intomicrosoft:mainfrom
Conversation
…ariant causes circular emit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
When a TypeSpec model uses
@discriminatoron a base type and all subtypes are referenced through a named union, the first variant in the union is silently dropped from the generateddiscriminator.mappingin the OpenAPI output.Example:
Generated (broken):
Root Cause
getDiscriminatorMappingcallsemitTypeReferencefor each derived model. The first variant in the union (NormalPokemon) is already mid-emission whenapplyDiscriminatorruns — because emittingNormalPokemontriggered the emission of its basePokemon, which immediately callsapplyDiscriminator.For a model that is currently being emitted,
emitTypeReferencereturns aPlaceholder(to handle the circular reference). The existing code does:Placeholderhas no$refproperty, so this evaluates toundefined. ThePlaceholderdoes resolve correctly later (via itsonValuecallback mechanism), but nobody registered a listener to update the mapping — somapping["normal"]staysundefinedand is silently dropped during YAML serialisation.The second and third variants (
LegendaryPokemon,MythicalPokemon) are not yet in the emit stack at this point, so theiremitTypeReferencecalls return proper declarations and their$refvalues are captured correctly.Fix
Check whether
ref.valueis aPlaceholder. If so, register anonValuelistener that writes the resolved$refinto the mapping once the circular reference unwinds.Placeholderis already imported in this file.The
onValuecallback fires before YAML serialisation, so the mapping object is complete by the time the output is written.