Skip to content

[core] Resolve oneOf discriminator type when property is inherited by alternatives#6

Open
Ignacio-Vidal wants to merge 1 commit into
masterfrom
recursive-discriminator-lookup
Open

[core] Resolve oneOf discriminator type when property is inherited by alternatives#6
Ignacio-Vidal wants to merge 1 commit into
masterfrom
recursive-discriminator-lookup

Conversation

@Ignacio-Vidal

Copy link
Copy Markdown
Owner

Problem

When a oneOf/anyOf interface declares the discriminator on itself but does not define the discriminator property locally, the discriminator property type was resolved as String instead of the actual type.

This happens when each alternative inherits the discriminator property from a shared base via allOf, while the discriminator keyword lives on the oneOf interface schema rather than on the base.

Concrete repro (jaxrs-spec, useOneOfInterfaces):

  • PetRequestV2 declares properties.petType: $ref PetType inline on the schema → generated PetType getPetType();
  • PetRequestV3 has no properties on the schema; petType is defined in a shared base referenced by each alternative's allOf → generated String getPetType();

Upstream PR OpenAPITools#24158 fixed the related case where the discriminator lives on the shared base and is inherited by the alternatives, but not this variant where the discriminator sits on the oneOf interface itself.

Fix

DiscriminatorUtils.recursiveGetDiscriminator now descends into the schema's oneOf/anyOf/allOf alternatives (cycle-guarded) to discover the discriminator property schema when the interface schema does not define it locally. The generated interface getter then uses the concrete type (e.g. an enum) rather than falling back to String.

The change is a strictly additive fallback: it only fires when the previous code returned null for the discriminator schema (which is exactly the case that fell back to String).

Tests

  • New testOneOfDiscriminatorOnInterfacePropertyInAlternatives in DefaultCodegenTest asserting the resolved type is the enum (PetType) and getIsEnum() is true.
  • New schemas (PetRequestV3, PetV3Base, CatRequestV3, DogRequestV3) in oneOfDiscriminator.yaml modelling the discriminator-on-interface + property-in-alternatives pattern.

Verification

  • DefaultCodegenTest (171), JavaJAXRSSpecServerCodegenTest (148), plus JavaClientCodegenTest, SpringCodegenTest, JavaHelidonCommonCodegenTest, JavaMicronautClientCodegenTest — all pass, no regressions.
  • Regenerated a real-world contract end-to-end: PetRequestV3 now emits PetType getPetType();; PetRequestV2 unchanged.

Note: samples were not regenerated in this PR — worth confirming via CI whether any committed sample matches this pattern.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Lw5PwrLknPHfsnkwTu2N1B

… alternatives

When a oneOf/anyOf interface declares the discriminator on itself but does
not define the discriminator property locally, the property type was resolved
as String instead of the actual type. This happens when each alternative
inherits the discriminator property from a shared base via allOf, while the
discriminator keyword lives on the oneOf interface schema rather than on the
base.

recursiveGetDiscriminator now descends into the schema's oneOf/anyOf/allOf
alternatives (cycle-guarded) to discover the discriminator property schema
when the interface schema does not define it locally, so the generated
interface getter uses the concrete type (e.g. an enum) rather than falling
back to String.

Adds a DefaultCodegenTest case and matching schemas in oneOfDiscriminator.yaml.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lw5PwrLknPHfsnkwTu2N1B
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