openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[Kotlin][BUG] `JsonClassDiscriminator` is not escaped

Open rlnt opened this issue 1 month ago • 0 comments

Bug Report Checklist

  • [X] Have you provided a full/minimal spec to reproduce the issue?
  • [X] Have you validated the input using an OpenAPI validator?
  • [ ] Have you tested with the latest master to confirm the issue still exists?
  • [X] Have you searched for related issues/PRs?
  • [X] What's the actual output vs expected output?
  • [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When using polymorphism with a class discriminator, symbols are not correctly escaped.

This is my spec

{
    "ReportParameterSchema_ReportParameterPropertyBase": {
        "type": "object",
        "discriminator": {
            "propertyName": "$type",
            "mapping": {
                "NumericParameterProperty": "#/components/schemas/ReportParameterSchema_NumericParameterProperty"
            }
        },
        "x-abstract": true,
        "additionalProperties": false,
        "required": ["key", "required", "$type"],
        "properties": {
            "key": {
                "type": "string",
                "minLength": 1
            },
            "required": {
                "type": "boolean"
            },
            "title": {
                "nullable": true,
                "type": "string"
            },
            "$type": {
                "type": "string"
            }
        }
    },
    "ReportParameterSchema_NumericParameterProperty": {
        "allOf": [
            {
                "$ref": "#/components/schemas/ReportParameterSchema_ReportParameterPropertyBase"
            },
            {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "minimum": {
                        "type": "number",
                        "format": "decimal",
                        "nullable": true
                    },
                    "maximum": {
                        "type": "number",
                        "format": "decimal",
                        "nullable": true
                    },
                    "multipleOf": {
                        "type": "number",
                        "format": "decimal",
                        "nullable": true
                    }
                }
            }
        ]
    }
}

The discriminator that links to polymorphism has the name $type. When generating the Kotlin client, it will generate as follows

@JsonClassDiscriminator(discriminator = "dollarType")
sealed class ReportParameterSchemaReportParameterPropertyBase {
    // ...
}

When trying out different things, I also noticed that something like sub_type becomes subType, which will mess with the serializers since this name has to match the actual name being used.

I currently work around it by editing the data_class.mustache template file, in which I hardcoded "\$type", but it would be nice if this could be fixed. The issue is that the {{{discriminator.propertyName}}} variable used inside the template holds an unescaped discriminator.

openapi-generator version

0.17.0

Generation Details

I am using the Gradle plugin to generate the client. This is the config. The spec file is downloaded from the backend.

openApiGenerate {
    generatorName = "kotlin"
    inputSpec = openApiSpecFile.map { it.asFile.path }
    templateDir = "${rootDir.absolutePath}/.openapi/templates"
    outputDir = layout.buildDirectory.dir("generated/openapi")
        .map { it.asFile.path }
    typeMappings.put(
        "kotlinx.datetime.Instant",
        "kotlin.time.Instant"
    )
    importMappings.put(
        "kotlinx.datetime.Instant",
        "kotlin.time.Instant"
    )
    packageName = "${appId}.openapi"
    generateModelTests = false
    generateApiTests = false
    cleanupOutput = true
    configOptions = mapOf(
        "dateLibrary" to "kotlinx-datetime",
        // "enumPropertyNaming" to "UPPERCASE", // currently bugged
        "library" to "multiplatform",
        "omitGradlePluginVersions" to "true",
        "omitGradleWrapper" to "true",
        // currently bugged, produces double serializable annotations, automatically set with "library" to "multiplatform"
        // https://github.com/OpenAPITools/openapi-generator/issues/18904
        // "serializationLibrary" to "kotlinx_serialization",
        "sourceFolder" to "commonMain/kotlin",
    )
}
Related issues

Polymorphism seems to be a problem with Kotlin clients in general. But after fixing the descriptor, things worked fine. I read a lot about polymorphism in this issue, but I don't think the discriminator issue is related. I only used it because it stated to drop the oneOf property in the spec and only keep the discriminator, which worked fine.

rlnt avatar Dec 09 '25 11:12 rlnt