diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache index 0ddf4793a444..1012709fd516 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache @@ -38,6 +38,10 @@ import kotlinx.parcelize.Parcelize import kotlinx.serialization.* import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* +{{#discriminator}}import kotlinx.serialization.json.JsonContentPolymorphicSerializer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.jsonObject +{{/discriminator}} {{/multiplatform}} {{#serializableModel}} import java.io.Serializable @@ -57,18 +61,18 @@ import {{packageName}}.infrastructure.ITransformForStorage {{#parcelizeModels}} @Parcelize {{/parcelizeModels}} -{{#multiplatform}}{{^discriminator}}@Serializable{{/discriminator}}{{/multiplatform}}{{#kotlinx_serialization}}{{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}}{{/kotlinx_serialization}}{{#moshi}}{{#moshiCodeGen}}@JsonClass(generateAdapter = true){{/moshiCodeGen}}{{/moshi}}{{#jackson}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{/jackson}} +{{#multiplatform}}@Serializable{{#discriminator}}(with = {{classname}}Serializer::class){{/discriminator}}{{/multiplatform}}{{#kotlinx_serialization}}{{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}}{{/kotlinx_serialization}}{{#moshi}}{{#moshiCodeGen}}@JsonClass(generateAdapter = true){{/moshiCodeGen}}{{/moshi}}{{#jackson}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{/jackson}} {{#isDeprecated}} @Deprecated(message = "This schema is deprecated.") {{/isDeprecated}} {{>additionalModelTypeAnnotations}} -{{#nonPublicApi}}internal {{/nonPublicApi}}{{#discriminator}}interface{{/discriminator}}{{^discriminator}}data class{{/discriminator}} {{classname}}{{^discriminator}} ( +{{#nonPublicApi}}internal {{/nonPublicApi}}{{#discriminator}}sealed class{{/discriminator}}{{^discriminator}}data class{{/discriminator}} {{classname}}{{^discriminator}} ( {{#allVars}} {{#required}}{{>data_class_req_var}}{{/required}}{{^required}}{{>data_class_opt_var}}{{/required}}{{^-last}},{{/-last}} {{/allVars}} -){{/discriminator}}{{#parent}}{{^serializableModel}}{{^parcelizeModels}} : {{{parent}}}{{#isMap}}(){{/isMap}}{{#isArray}}(){{/isArray}}{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{^parcelizeModels}} : {{{parent}}}{{#isMap}}(){{/isMap}}{{#isArray}}(){{/isArray}}, Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{^serializableModel}}{{#parcelizeModels}} : {{{parent}}}{{#isMap}}(){{/isMap}}{{#isArray}}(){{/isArray}}, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{#parcelizeModels}} : {{{parent}}}{{#isMap}}(){{/isMap}}{{#isArray}}(){{/isArray}}, Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{^parcelizeModels}} : Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{#parcelizeModels}} : Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#generateRoomModels}}{{#parent}}, {{/parent}}{{^discriminator}}{{^parent}}:{{/parent}} ITransformForStorage<{{classname}}RoomModel>{{/discriminator}}{{/generateRoomModels}}{{#vendorExtensions.x-has-data-class-body}} { +){{/discriminator}}{{#parent}}{{^serializableModel}}{{^parcelizeModels}} : {{{parent}}}(){{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{^parcelizeModels}} : {{{parent}}}(), Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{^serializableModel}}{{#parcelizeModels}} : {{{parent}}}(), Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{#parcelizeModels}} : {{{parent}}}(), Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{^parcelizeModels}} : Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{#parcelizeModels}} : Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#generateRoomModels}}{{#parent}}, {{/parent}}{{^discriminator}}{{^parent}}:{{/parent}} ITransformForStorage<{{classname}}RoomModel>{{/discriminator}}{{/generateRoomModels}}{{#vendorExtensions.x-has-data-class-body}} { {{/vendorExtensions.x-has-data-class-body}} {{#generateRoomModels}} companion object { } @@ -146,3 +150,13 @@ import {{packageName}}.infrastructure.ITransformForStorage {{#vendorExtensions.x-has-data-class-body}} } {{/vendorExtensions.x-has-data-class-body}} +{{#discriminator}} + +internal object {{classname}}Serializer : JsonContentPolymorphicSerializer<{{classname}}>({{classname}}::class) { + override fun selectDeserializer(element: JsonElement) = when { + {{#mappedModels}} + "{{mappingName}}" in element.jsonObject["{{discriminatorName}}"].toString() -> {{modelName}}.serializer() + {{/mappedModels}} + else -> {{classname}}.serializer() + } +}{{/discriminator}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/interface_req_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/interface_req_var.mustache index 743069ff554d..241bf514b0e0 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/interface_req_var.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/interface_req_var.mustache @@ -15,4 +15,4 @@ {{^isEnum}}{{^isArray}}{{^isPrimitiveType}}{{^isModel}}@Contextual {{/isModel}}{{/isPrimitiveType}}{{/isArray}}{{/isEnum}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") {{/kotlinx_serialization}} {{/multiplatform}} - {{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required {{/multiplatform}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInCamelCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInCamelCase}}}{{/isArray}}{{/isEnum}}{{#isNullable}}?{{/isNullable}} \ No newline at end of file + {{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required {{^isInherited}}abstract {{/isInherited}}{{/multiplatform}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInCamelCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInCamelCase}}}{{/isArray}}{{/isEnum}}{{#isNullable}}?{{/isNullable}} \ No newline at end of file diff --git a/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/models/Animal.kt b/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/models/Animal.kt index f3a877f5a8ea..62300942a107 100644 --- a/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/models/Animal.kt +++ b/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/models/Animal.kt @@ -25,9 +25,15 @@ import com.squareup.moshi.Json */ -interface Animal { +sealed class Animal { @Json(name = "id") val id: java.util.UUID } +internal object AnimalSerializer : JsonContentPolymorphicSerializer(Animal::class) { + override fun selectDeserializer(element: JsonElement) = when { + "BIRD" in element.jsonObject["type"].toString() -> Bird.serializer() + else -> Animal.serializer() + } +} diff --git a/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/models/Bird.kt b/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/models/Bird.kt index 64a248fcc3bd..8b06fad79768 100644 --- a/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/models/Bird.kt +++ b/samples/client/petstore/kotlin-allOff-discriminator/src/main/kotlin/org/openapitools/client/models/Bird.kt @@ -35,5 +35,5 @@ data class Bird ( @Json(name = "featherType") val featherType: kotlin.String -) : Animal +) : Animal()