OpenAPITools / OpenAPITools/openapi-generator

[BUG][Kotlin] `isEnum` and `default` not detected integer enums

Open
#22,206 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Description

The template's placeholder isEnum is incorrectly resolved to false for integer enums in the Kotlin client. default values are also not being recognized.

openapi-generator version

7.16.0

OpenAPI declaration
      "Filter": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "propertyName": {
            "type": "string"
          },
          "filterValue": {
            "type": "string"
          },
          "caseSensitive": {
            "type": "boolean"
          },
          "operation": {
            "default": 0,
            "oneOf": [
              {
                "$ref": "#/components/schemas/FilterOperation"
              }
            ]
          }
        }
      },
      "FilterOperation": {
        "type": "integer",
        "description": "",
        "x-enumNames": ["Contains", "Equals", "StartsWith", "EndsWith", "GreaterThan", "LessThan", "NotEquals", "GreaterThanOrEqual", "LessThanOrEqual", "In", "NotIn"],
        "enum": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        "x-enum-varnames": ["Contains", "Equals", "StartsWith", "EndsWith", "GreaterThan", "LessThan", "NotEquals", "GreaterThanOrEqual", "LessThanOrEqual", "In", "NotIn"]
      }
Generation Details

I am using the Gradle plugin for the OpenAPI generation. I am developing for Kotlin Multiplatform.

openApiGenerate {
    generatorName = "kotlin"
    remoteInputSpec = openApiSpecUrl
    templateDir = "${rootDir.absolutePath}/.openapi/templates"
    outputDir = layout.buildDirectory.dir("generated/openapi")
        .get().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",
        "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"
    )
}

The FilterOperation integer enum is correctly generated as follows

@Serializable(with = FilterOperationSerializer::class)
enum class FilterOperation(val value: kotlin.Int) {
    Contains(0),
    Equals(1),
    StartsWith(2),
    EndsWith(3),
    GreaterThan(4),
    LessThan(5),
    NotEquals(6),
    GreaterThanOrEqual(7),
    LessThanOrEqual(8),
    In(9),
    NotIn(10);

    // serializer stuff ...

The Filter data class is correctly generated except for the operation default value, although it's present in the spec via default: 0.

@Serializable
data class Filter (
    @SerialName(value = "propertyName") val propertyName: kotlin.String,
    @SerialName(value = "filterValue") val filterValue: kotlin.String,
    @SerialName(value = "caseSensitive") val caseSensitive: kotlin.Boolean = true,
    // missing default value
    @SerialName(value = "operation") val operation: FilterOperation
) {
}

Checking the template file used for generating this data_class_opt_var.mustache, there are several checks for isEnum. But I edited the template to include the following info.

    //Param Info
    //enum: {{#isEnum}}yes{{/isEnum}}{{^isEnum}}no{{/isEnum}}
    //defaultValue: {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}no{{/defaultValue}}
    //nullable: {{#isNullable}}yes{{/isNullable}}{{^isNullable}}no{{/isNullable}}

And now I am getting this.

@Serializable
data class Filter (
    //Param Info
    //enum: no
    //defaultValue: no
    //nullable: no
    @SerialName(value = "propertyName") val propertyName: kotlin.String,
    //Param Info
    //enum: no
    //defaultValue: no
    //nullable: no
    @SerialName(value = "filterValue") val filterValue: kotlin.String,
    //Param Info
    //enum: no
    //defaultValue: true
    //nullable: no
    @SerialName(value = "caseSensitive") val caseSensitive: kotlin.Boolean = true,
    //Param Info
    //enum: no
    //defaultValue: no
    //nullable: no
    @SerialName(value = "operation") val operation: FilterOperation
) {
}

That means isEnum is false for FilterOperation, although it's correctly being generated as an integer enum. Additionally, it says it has no default value. even though it's given in the spec.

Related issues/PRs

It might be somewhat related to this, but I already fixed the multiplatform enum integer generation locally which I submitted as PR already.
https://github.com/OpenAPITools/openapi-generator/issues/21204

Suggest a fix

The default value and enum detection need to be fixed for Kotlin integer enums.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the Kotlin generation with the supplied OpenAPI declaration and inspect the data_class_opt_var.mustache template context for the operation property. Compare the integer enum and default metadata with the generated FilterOperation and Filter output; done means isEnum and defaultValue are populated correctly for the generated Kotlin data class.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin, openapi
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.