OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
20.63k stars 6.29k forks source link

[BUG] [kotlin-spring] Unbalanced parenthesis in generated function declarations when using default value #18854

Closed Humle-T closed 1 month ago

Humle-T commented 1 month ago

Bug Report Checklist

Description

When using default values for path parameters, the generated output has unbalanced parenthesis, leading to code that cannot compile. It seems to be an issue with a .mustache-template, which also has unbalanced parenthesis.

openapi-generator version

I am using the docker-image openapitools/openapi-generator-cli:latest. Checking the version with $ docker run --rm -v "${PWD}/:/input" -v "${PWD}:/output" openapitools/openapi-generator-cli:latest version outputs 7.7.0-SNAPSHOT

OpenAPI declaration file content or url

Link to Gist with openapi.yaml

Generation Details

I run the generator with the following docker command, having the openapi.yaml in the current directory:

docker run --rm -v "${PWD}/:/input" -v "${PWD}:/output" openapitools/openapi-generator-cli:latest generate \
    -i input/openapi.yaml \
    -g kotlin-spring  \
    -o output/client
Steps to reproduce

With the provided openapi.yaml in the current working directory, I run the generator with the docker command above. The generated Kotlin class that is causing trouble is defined in /client/src/main/kotlin/org/openapitools/api/ExampleApiController.kt A Gist of the generated class can be found here At Line 47 and Line 62, right after the schema = Schema(...)-definitions, it seems there's a ) missing (2 - one in each line).

I would expect the lines to be: fun exampleFirstSomeParameterGet(@Parameter(description = "", required = true, schema = Schema(defaultValue = "abc")) @PathVariable("someParameter") someParameter: kotlin.String): ResponseEntity<Unit> { and fun exampleSecondSomeOtherParameterGet(@Parameter(description = "", required = true, schema = Schema(allowableValues = ["\"def\"", "\"123\""], defaultValue = "def")) @PathVariable("someOtherParameter") someOtherParameter: kotlin.String): ResponseEntity<Unit> {

Related issues/PRs

I did not find any similar issues, when looking for kotlin-spring issues.

Suggest a fix

If I create a new file, pathParams.mustache (and place it next to the openapi.yaml) with the following content (on one line): {{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#enumVars}}"{{#lambdaEscapeInNormalString}}{{{value}}}{{/lambdaEscapeInNormalString}}"{{^-last}}, {{/-last}}{{/enumVars}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#enumVars}}"{{#lambdaEscapeInNormalString}}{{{value}}}{{/lambdaEscapeInNormalString}}"{{^-last}}, {{/-last}}{{/enumVars}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#enumVars}}{{#lambda.escapeDoubleQuote}}{{{value}}}{{/lambda.escapeDoubleQuote}}{{^-last}}, {{/-last}}{{/enumVars}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} @PathVariable("{{baseName}}") {{{paramName}}}: {{>optionalDataType}}{{/isPathParam}} and I run the generator, using this overriding template, like so: docker run --rm -v "${PWD}/:/input" -v "${PWD}:/output" openapitools/openapi-generator-cli:latest generate \ -i input/openapi.yaml \ -t input/ \ -g kotlin-spring \ -o output/client I get the expected output.

But with my limited .mustache-skills, this might need a look over by someone more experienced. (I find it kind of hard to read and reason about the rather large one-liner above ;) )

Thank you!

wing328 commented 1 month ago

can you please file a PR with the suggested ix to start with?

Humle-T commented 1 month ago

@wing328 I can indeed. PR #18861

As mentioned in the PR description, on further inspection, I think my first suggestion for a fix was slightly wrong. For anyone using the overriding template, as a workaround until the PR is merged, try this in pathParams.mustache instead: {{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#enumVars}}"{{#lambdaEscapeInNormalString}}{{{value}}}{{/lambdaEscapeInNormalString}}"{{^-last}}, {{/-last}}{{/enumVars}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#enumVars}}"{{#lambdaEscapeInNormalString}}{{{value}}}{{/lambdaEscapeInNormalString}}"{{^-last}}, {{/-last}}{{/enumVars}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#enumVars}}{{#lambda.escapeDoubleQuote}}{{{value}}}{{/lambda.escapeDoubleQuote}}{{^-last}}, {{/-last}}{{/enumVars}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} @PathVariable("{{baseName}}") {{{paramName}}}: {{>optionalDataType}}{{/isPathParam}}

Humle-T commented 1 month ago

Thank you for quick and efficient issue/PR handling! 👍