OpenAPITools / OpenAPITools/openapi-generator
[BUG][Kotlin] `isEnum` and `default` not detected integer enums
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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