feat(gen): add value-based oneOf/anyOf discrimination#1588
Merged
ernado merged 4 commits intoogen-go:mainfrom Nov 30, 2025
Merged
feat(gen): add value-based oneOf/anyOf discrimination#1588ernado merged 4 commits intoogen-go:mainfrom
ernado merged 4 commits intoogen-go:mainfrom
Conversation
Add support for discriminating oneOf/anyOf schemas based on enum field values when field names and JSON types are identical across variants. This introduces a new automatic discrimination strategy that complements the type-based discrimination added in 40e0719. When schemas share field names with the same JSON type but different enum values, ogen now generates efficient switch statements on those values instead of failing with a type conflict error. Changes: - Add ValueDiscriminator IR metadata structure to capture enum-based discrimination patterns - Implement detection and validation logic in schema_gen_sum.go to identify discriminable enum fields across oneOf/anyOf variants - Generate value-based discrimination code via json/encoders_sum.tmpl template with proper nil returns after enum switches - Fix Faker to skip parent fields that overlap with inline sum variant fields, preventing duplicate JSON key generation - Document the new discrimination strategy in README.md - Add comprehensive test coverage with positive (3 scenarios) and negative (overlap detection) specs This is the 5th automatic discrimination strategy, enabling more flexible schema designs without requiring explicit discriminator mappings.
07e5a26 to
a856421
Compare
…minate When multiple fields could potentially be used for value-based discrimination, if one field has overlapping enum values across variants, continue checking other fields instead of immediately failing. Only fail if NO field can discriminate. This fixes cases like: - Carrier field with disjoint values (usps, fedex) - Signature field with overlapping values (gift, sample in both) Now ogen will use the carrier field for discrimination and ignore the overlapping signature field.
ernado
approved these changes
Nov 30, 2025
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.
Add value-based oneOf/anyOf discrimination
Problem
ogen currently rejects schemas where oneOf/anyOf variants have the same field name and JSON type, even when enum values are different:
Error:
type-based discrimination with same jxTypeThis blocks common patterns: status-based APIs, event systems with eventType enums, Kubernetes-style resource types, and state machines.
Solution
Adds value-based discrimination as a 5th automatic discrimination strategy. When variants share a field name and JSON type but have different enum values, ogen now:
Example generated code for
statusfield:Overlapping Values Handling
When one field has overlapping enum values but another field can discriminate, ogen uses the discriminating field:
Testing
Changes
gen/ir/type.go: AddedValueDiscriminatormetadata structuregen/schema_gen_sum.go: Added detection and validation logic (~150 lines)gen/_template/json/encoders_sum.tmpl: Added value discrimination templategen/ir/faker.go: Fixed faker to skip parent fields that overlap with oneOf variant fields (prevents duplicate JSON keys)README.md: Documented new discrimination strategyBackward Compatibility
✅ No breaking changes. Purely additive:
Related Issues
May help with #491 (anyOf discriminator support), #1230 (oneOf decode), #1480 (nested sum types).
Complements commit 40e0719 which added type-based discrimination.
Performance
String value checking is O(n) for n enum values, but: