fix(kotlin-client): use escaped propertyBaseName for JsonClassDiscriminator
Fixes #22523
Problem
The kotlinx_serialization and multiplatform templates in kotlin-client/data_class.mustache emitted discriminator.propertyName. DefaultCodegen sets that field through toVarName() (DefaultCodegen.java:3770), so it is a sanitized Kotlin identifier rather than the wire-format name — a discriminator declared as $type was emitted as dollarType.
This left the generated client internally inconsistent. oneof_class.mustache already writes and reads the discriminator using propertyBaseName (lines 142, 154), and typeInfoAnnotation.mustache uses propertyBaseName in kotlin-client, kotlin-server, and kotlin-spring. These two annotation lines were the only remaining uses of propertyName.
Fix
Switch both lines to propertyBaseName, wrapped in lambda.escapeDollar — the same lambda already used ~40 times in this file for baseName — because the raw name lands inside a Kotlin string literal, where an unescaped $ begins an interpolation.
Verification
Same spec, same command, only the template differs:
| template | generated |
|---|---|
| before | discriminator = "dollarType" |
propertyBaseName alone | discriminator = "$type" — correct name, does not compile |
propertyBaseName + escapeDollar | discriminator = "\$type" — correct and compiles |
./gradlew compileKotlin passes on the generated kotlin-allOf-special-discriminator-kotlinx-serialization sample.
Regenerating all bin/configs/kotlin-*.yaml produces no diff in existing samples — every current spec uses a discriminator that is already a valid identifier, so toVarName() was a no-op there.
New samples
Adds polymorphism-special-discriminator.yaml (a copy of the existing polymorphism.yaml with a $type discriminator) plus two configs covering both affected templates, giving CI a regression case.
Relation to #23633
That draft addresses Kotlin escaping broadly but is currently blocked on build failures. This is a narrow, independent fix for the discriminator case only.
cc @karismann @Zomzog @andrewemery @4brunu @yutaka0m @stefankoppier @e5l @dennisameling
PR checklist
- Read the contribution guidelines.
- Run the following to build the project and update samples:
(For Windows users, please run the script in WSL)./mvnw clean package || exit ./bin/generate-samples.sh ./bin/configs/*.yaml || exit ./bin/utils/export_docs_generators.sh || exit
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example./bin/generate-samples.sh bin/configs/java*.
IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed. - If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.
Summary by cubic
Fixes Kotlin client generation for polymorphic discriminators when using kotlinx-serialization and the multiplatform library. Previously, @JsonClassDiscriminator used a transformed name (e.g., $type -> dollarType), which disagreed with oneof_class.mustache and broke serialization; now it uses the raw discriminator name with escaped dollars. Fixes #22523.
- Update
modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustacheto usediscriminator.propertyBaseNamewrapped withlambda.escapeDollarin bothkotlinx_serializationandmultiplatformpaths. - Add a test spec with a
$typediscriminator and generate samples forkotlinx-serializationand multiplatform to validate the fix.