Commit 1af1d1c
[kotlin-spring] Add sealed class polymorphism support via useSealedDiscriminatorClasses option
Add opt-in `useSealedDiscriminatorClasses` configuration option (default `false`) that enables proper polymorphism support for the kotlin-spring generator using sealed classes instead of interfaces.
When enabled, discriminator parent models are generated as Kotlin sealed classes with proper Jackson `@JsonTypeInfo`/`@JsonSubTypes` annotations. Child classes extend the parent via constructor inheritance with `override` properties. This approach mirrors the polymorphism support added to the kotlin-server generator in OpenAPITools#22610.
The motivation for this change is that the current interface-based polymorphism has several long-standing issues: parent interfaces incorrectly contain all children's properties, child classes don't properly implement the parent interface, the `override` keyword is missing on inherited properties, and multi-level inheritance produces invalid data class hierarchies that don't compile. These issues have been tracked across multiple GitHub issues over several years.
The implementation adds a `postProcessAllModels()` method (ported from `KotlinServerCodegen`) that builds parent-child relationships for discriminator models in three passes: first collecting discriminator mappings, then processing child models to mark inherited properties and generate parent constructor arguments, and finally configuring vendor extensions that control the template rendering.
Both oneOf (type union) and allOf (inheritance) discriminator patterns are supported. For oneOf, the parent sealed class contains only the discriminator property; children get the discriminator as an overridden property with a default value. For allOf, the parent sealed class contains all its declared properties; children override inherited properties and pass them via the parent constructor call.
A companion `fixJacksonJsonTypeInfoInheritance` option (default `true`, only applies when sealed classes are enabled) controls whether Jackson's `visible` flag is set to `true` on `@JsonTypeInfo` and whether discriminator properties are automatically added to child models with appropriate default values.
The default behavior (`useSealedDiscriminatorClasses=false`) is completely unchanged — existing users continue to get interface-based generation with zero sample file changes. This makes the change non-breaking and suitable for a minor release.
New template `dataClassSealedVar.mustache` renders sealed class constructor properties with `open`/`override` modifiers and `@get:Schema`/`@get:JsonProperty` annotations. The existing `dataClass.mustache` and `typeInfoAnnotation.mustache` templates are updated to conditionally render either interface or sealed class based on the flag.
Six new test methods cover oneOf with discriminator, allOf with discriminator, polymorphism without discriminator, and the `fixJacksonJsonTypeInfoInheritance` toggle. All 149 existing tests continue to pass.
Fixes OpenAPITools#18167, OpenAPITools#18206, OpenAPITools#11347, OpenAPITools#8060
Related: OpenAPITools#8366, OpenAPITools#8059
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent 03c13fb commit 1af1d1c
6 files changed
Lines changed: 501 additions & 7 deletions
File tree
- docs/generators
- modules/openapi-generator/src
- main
- java/org/openapitools/codegen/languages
- resources/kotlin-spring
- test/java/org/openapitools/codegen/kotlin/spring
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
61 | 62 | | |
62 | 63 | | |
63 | 64 | | |
| 65 | + | |
64 | 66 | | |
65 | 67 | | |
66 | 68 | | |
| |||
307 | 309 | | |
308 | 310 | | |
309 | 311 | | |
310 | | - | |
| 312 | + | |
311 | 313 | | |
312 | | - | |
| 314 | + | |
313 | 315 | | |
314 | 316 | | |
315 | 317 | | |
| |||
0 commit comments