Skip to content

feat: add discriminator support for JSON schema validation#292

Merged
aeschli merged 4 commits intomicrosoft:mainfrom
mohankumarelec:discriminator
Dec 1, 2025
Merged

feat: add discriminator support for JSON schema validation#292
aeschli merged 4 commits intomicrosoft:mainfrom
mohankumarelec:discriminator

Conversation

@mohankumarelec
Copy link
Copy Markdown
Contributor

Add Discriminator Support for JSON Schema Validation

Overview

This PR introduces discriminator support for JSON schema validation, significantly improving performance for schemas using oneOf, anyOf, and allOf by intelligently selecting which schema alternatives to test based on a discriminator property.

Problem Solved

Without discriminators, the validator must test all schema alternatives in oneOf/anyOf/allOf, leading to exponential complexity in deeply nested or self-referencing schemas. This causes severe performance degradation and can even make validation impractically slow for certain schema patterns.

See the test case self-referencing schema with anyOf and deep nesting (exploding complexity test) for a concrete example.

Implementation

Added discriminator support with two modes:

  1. propertyName: Discriminate based on an object property (e.g., "type": "cat")
  2. propertyIndex: Discriminate based on the first N properties or array items

The discriminator can include an explicit mapping object to map discriminator values to schema indices, or auto-detect based on const values in the alternative schemas.

Example:

{
  oneOf: [
    { properties: { type: { const: 'cat' }, meow: { type: 'boolean' } } },
    { properties: { type: { const: 'dog' }, bark: { type: 'boolean' } } }
  ],
  discriminator: {
    propertyName: 'type',
    mapping: { 'cat': 0, 'dog': 1 }
  }
}

Test Coverage

Added tests for:

  • ✅ Basic discriminator with propertyName and propertyIndex
  • ✅ Discriminator with oneOf, anyOf
  • ✅ Missing/invalid discriminator values (graceful fallback)
  • ✅ Complex nested objects
  • ✅ Non-string discriminator values
  • ✅ Auto-detection without explicit mapping
  • Deep nesting with self-referencing schemas (100 levels)

Performance Impact

For schemas with discriminators, validation performance improves significantly. This is especially critical for self-referencing schemas with deep nesting.

@mohankumarelec
Copy link
Copy Markdown
Contributor Author

@aeschli , Can you please look into this PR when you have some time. Thanks a lot

@aeschli
Copy link
Copy Markdown
Collaborator

aeschli commented Nov 2, 2025

It's a VS Code only extension of schemas and only schemas with that new 'discriminator' property would profit.

We have other VS Code specific schemas extensions, but they are all in the space of improving the editing experience for our settings editors. We don't want to propagate them, and we don't want to create a new flavor of schemas.

Ideally the 'discriminator' could be computed when loading the schema. I'd prefer such a solution

@mohankumarelec
Copy link
Copy Markdown
Contributor Author

@aeschli , Thanks for the feedback. I have removed the discriminator property since it deviates from official JSON schema, and i have added now an tryDiscriminatorOptimization function, where it will try to optimize if it finds a discriminator pattern. This way all the existing applications will also get benefited without explicitly defining a discriminator property.

I have also added a test case named self-referencing schema with anyOf and deep nesting (exploding complexity test), which will get stuck for a very long time, if the tryDiscriminatorOptimization is disabled.

@aeschli
Copy link
Copy Markdown
Collaborator

aeschli commented Dec 1, 2025

Thanks @mohankumarelec. I polished the code a bit, hope that's ok.

@aeschli aeschli enabled auto-merge (squash) December 1, 2025 19:08
@aeschli aeschli merged commit 1e06466 into microsoft:main Dec 1, 2025
3 checks passed
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.

3 participants