Repository: cjbooms/fabrikt
Pull request #200 (2023-04-22 09:42:07)

Fixes snake case polymorphic schema names.
Closes Issue #199

cjbooms: 👍 
averabaq: 👍 

Patch:
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/generators/PropertyUtils.kt b/src/main/kotlin/com/cjbooms/fabrikt/generators/PropertyUtils.kt
index d78d221..de60641 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/generators/PropertyUtils.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/generators/PropertyUtils.kt
@@ -27,6 +27,7 @@ data class ClassSettings(
 object PropertyUtils {
     fun PropertyInfo.addToClass(
         modelName: String,
+        schemaName: String,
         type: TypeName,
         parameterizedType: TypeName,
         classBuilder: TypeSpec.Builder,
@@ -86,7 +87,7 @@ object PropertyUtils {
                 ClassSettings.PolymorphyType.SUB -> {
                     if (this is PropertyInfo.Field && isPolymorphicDiscriminator) {
                         property.addModifiers(KModifier.OVERRIDE)
-                        val discriminators = maybeDiscriminator.getDiscriminatorMappings(modelName)
+                        val discriminators = maybeDiscriminator.getDiscriminatorMappings(schemaName, modelName)
                         if (discriminators.size == 1) {
                             when (val discriminator = discriminators.first()) {
                                 is PropertyInfo.DiscriminatorKey.EnumKey ->
@@ -119,7 +120,7 @@ object PropertyUtils {
             if (this !is PropertyInfo.Field ||
                 !isPolymorphicDiscriminator ||
                 isSubTypeDiscriminatorWithNoValue(classSettings) ||
-                isSubTypeDiscriminatorWithMultipleValues(classSettings, modelName)
+                isSubTypeDiscriminatorWithMultipleValues(classSettings, modelName, schemaName)
             ) {
                 property.initializer(name)
                 val constructorParameter: ParameterSpec.Builder = ParameterSpec.builder(name, wrappedType)
@@ -145,8 +146,11 @@ object PropertyUtils {
 
     private fun Map<String, PropertyInfo.DiscriminatorKey>?.getDiscriminatorMappings(
         modelName: String,
+        schemaName: String,
     ): List<PropertyInfo.DiscriminatorKey> =
-        this?.filter { it.value.modelName == modelName }?.map { it.value }.orEmpty()
+        this?.filter {
+            it.value.stringValue == schemaName || it.value.modelName == modelName || it.value.modelName == schemaName
+        }?.map { it.value }.orEmpty()
 
     private fun PropertyInfo.Field.isSubTypeDiscriminatorWithNoValue(classType: ClassSettings) =
         classType.polymorphyType == ClassSettings.PolymorphyType.SUB &&
@@ -156,10 +160,11 @@ object PropertyUtils {
     private fun PropertyInfo.Field.isSubTypeDiscriminatorWithMultipleValues(
         classType: ClassSettings,
         modelName: String,
+        schemaName: String,
     ) =
         classType.polymorphyType == ClassSettings.PolymorphyType.SUB &&
             isPolymorphicDiscriminator &&
-            maybeDiscriminator.getDiscriminatorMappings(modelName).size > 1
+            maybeDiscriminator.getDiscriminatorMappings(modelName, schemaName).size > 1
 
     private fun getDefaultValue(propTypeInfo: PropertyInfo, parameterizedType: TypeName): OasDefault? {
         return when (propTypeInfo) {
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/generators/model/JacksonModelGenerator.kt b/src/main/kotlin/com/cjbooms/fabrikt/generators/model/JacksonModelGenerator.kt
index d4c1ab2..56ad9f5 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/generators/model/JacksonModelGenerator.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/generators/model/JacksonModelGenerator.kt
@@ -177,10 +177,12 @@ class JacksonModelGenerator(
         allSchemas: List<SchemaInfo>,
     ): TypeSpec {
         val modelName = schemaInfo.name.toModelClassName()
+        val schemaName = schemaInfo.name
         return when {
             schemaInfo.schema.isPolymorphicSuperType() && schemaInfo.schema.isPolymorphicSubType(api) ->
                 polymorphicSuperSubType(
                     modelName,
+                    schemaName,
                     properties,
                     checkNotNull(schemaInfo.schema.getDiscriminatorForInLinedObjectUnderAllOf()),
                     schemaInfo.schema.getSuperType(api)!!.let { SchemaInfo(it.name, it) },
@@ -190,6 +192,7 @@ class JacksonModelGenerator(
 
             schemaInfo.schema.isPolymorphicSuperType() -> polymorphicSuperType(
                 modelName,
+                schemaName,
                 properties,
                 schemaInfo.schema.discriminator,
                 schemaInfo.schema.extensions,
@@ -198,13 +201,14 @@ class JacksonModelGenerator(
 
             schemaInfo.schema.isPolymorphicSubType(api) -> polymorphicSubType(
                 modelName,
+                schemaName,
                 properties,
                 schemaInfo.schema.getSuperType(api)!!.let { SchemaInfo(it.name, it) },
                 schemaInfo.schema.extensions,
             )
 
             schemaInfo.typeInfo is KotlinTypeInfo.Enum -> buildEnumClass(schemaInfo.typeInfo)
-            else -> standardDataClass(modelName, properties, schemaInfo.schema.extensions)
+            else -> standardDataClass(modelName, schemaName, properties, schemaInfo.schema.extensions)
         }
     }
 
@@ -223,6 +227,7 @@ class JacksonModelGenerator(
                     val props = it.schema.topLevelProperties(HTTP_SETTINGS, enclosingSchema)
                     val currentModel = standardDataClass(
                         it.name.toModelClassName(enclosingModelName),
+                        it.name,
                         props,
                         it.schema.extensions,
                     )
@@ -239,6 +244,7 @@ class JacksonModelGenerator(
                         setOf(
                             standardDataClass(
                                 modelName = if (it.schema.isInlinedTypedAdditionalProperties()) it.schema.toMapValueClassName() else it.schema.toModelClassName(),
+                                schemaName = it.name,
                                 properties = it.schema.topLevelProperties(HTTP_SETTINGS, enclosingSchema),
                                 extensions = it.schema.extensions,
                             ),
@@ -265,6 +271,7 @@ class JacksonModelGenerator(
                                         apiDocUrl = apiDocUrl,
                                     ) + standardDataClass(
                                         modelName = it.name.toModelClassName(enclosingModelName),
+                                        schemaName = it.name,
                                         properties = props,
                                         extensions = it.schema.extensions,
                                     )
@@ -367,6 +374,7 @@ class JacksonModelGenerator(
             val schema = mapField.schema.additionalPropertiesSchema
             standardDataClass(
                 modelName = if (schema.isInlinedTypedAdditionalProperties()) schema.toMapValueClassName() else schema.toModelClassName(),
+                schemaName = schema.safeName(),
                 properties = mapField.schema.additionalPropertiesSchema.topLevelProperties(HTTP_SETTINGS),
                 extensions = mapField.schema.extensions,
             )
@@ -376,6 +384,7 @@ class JacksonModelGenerator(
 
     private fun standardDataClass(
         modelName: String,
+        schemaName: String,
         properties: Collection<PropertyInfo>,
         extensions: Map<String, Any>,
     ): TypeSpec {
@@ -387,6 +396,7 @@ class JacksonModelGenerator(
             .addCompanionObject()
         properties.addToClass(
             modelName = modelName,
+            schemaName = schemaName,
             classBuilder = classBuilder,
             classType = ClassSettings(ClassSettings.PolymorphyType.NONE, extensions.hasJsonMergePatchExtension),
         )
@@ -395,6 +405,7 @@ class JacksonModelGenerator(
 
     private fun polymorphicSuperSubType(
         modelName: String,
+        schemaName: String,
         properties: Collection<PropertyInfo>,
         discriminator: Discriminator,
         superType: SchemaInfo,
@@ -404,6 +415,7 @@ class JacksonModelGenerator(
         TypeSpec.classBuilder(generatedType(packages.base, modelName))
             .buildPolymorphicSubType(
                 modelName,
+                schemaName,
                 properties.filter(PropertyInfo::isInherited),
                 superType,
                 extensions,
@@ -411,6 +423,7 @@ class JacksonModelGenerator(
             )
             .buildPolymorphicSuperType(
                 modelName,
+                schemaName,
                 properties.filterNot(PropertyInfo::isInherited),
                 discriminator,
                 extensions,
@@ -422,16 +435,18 @@ class JacksonModelGenerator(
 
     private fun polymorphicSuperType(
         modelName: String,
+        schemaName: String,
         properties: Collection<PropertyInfo>,
         discriminator: Discriminator,
         extensions: Map<String, Any>,
         allSchemas: List<SchemaInfo>,
     ): TypeSpec = TypeSpec.classBuilder(generatedType(packages.base, modelName))
-        .buildPolymorphicSuperType(modelName, properties, discriminator, extensions, allSchemas)
+        .buildPolymorphicSuperType(modelName, schemaName, properties, discriminator, extensions, allSchemas)
         .build()
 
     private fun TypeSpec.Builder.buildPolymorphicSuperType(
         modelName: String,
+        schemaName: String,
         properties: Collection<PropertyInfo>,
         discriminator: Discriminator,
         extensions: Map<String, Any>,
@@ -468,6 +483,7 @@ class JacksonModelGenerator(
 
         properties.addToClass(
             modelName,
+            schemaName,
             constructorBuilder,
             this,
             ClassSettings(ClassSettings.PolymorphyType.SUPER, extensions.hasJsonMergePatchExtension),
@@ -478,14 +494,16 @@ class JacksonModelGenerator(
 
     private fun polymorphicSubType(
         modelName: String,
+        schemaName: String,
         properties: Collection<PropertyInfo>,
         superType: SchemaInfo,
         extensions: Map<String, Any>,
     ): TypeSpec = TypeSpec.classBuilder(generatedType(packages.base, modelName))
-        .buildPolymorphicSubType(modelName, properties, superType, extensions).build()
+        .buildPolymorphicSubType(modelName, schemaName, properties, superType, extensions).build()
 
     private fun TypeSpec.Builder.buildPolymorphicSubType(
         modelName: String,
+        schemaName: String,
         allProperties: Collection<PropertyInfo>,
         superType: SchemaInfo,
         extensions: Map<String, Any>,
@@ -513,6 +531,7 @@ class JacksonModelGenerator(
 
         properties.addToClass(
             modelName,
+            schemaName,
             constructorBuilder,
             this,
             ClassSettings(ClassSettings.PolymorphyType.SUB, extensions.hasJsonMergePatchExtension),
@@ -522,6 +541,7 @@ class JacksonModelGenerator(
 
     private fun Collection<PropertyInfo>.addToClass(
         modelName: String,
+        schemaName: String,
         constructorBuilder: FunSpec.Builder = FunSpec.constructorBuilder(),
         classBuilder: TypeSpec.Builder,
         classType: ClassSettings,
@@ -529,6 +549,7 @@ class JacksonModelGenerator(
         this.forEach {
             it.addToClass(
                 modelName,
+                schemaName,
                 toModelType(
                     packages.base,
                     it.typeInfo,
@@ -554,7 +575,7 @@ class JacksonModelGenerator(
 
     private fun Discriminator.getDiscriminatorMappings(schemaInfo: SchemaInfo): Map<String, TypeName> =
         mappingKeys(schemaInfo.schema)
-            .filter { it.value == schemaInfo.schema.name }
+            .filter { it.value == schemaInfo.schema.name || it.key == schemaInfo.schema.name }
             .map {
                 it.key to toModelType(packages.base, KotlinTypeInfo.from(schemaInfo.schema, schemaInfo.name))
             }


Test patch:
diff --git a/src/test/resources/examples/enumPolymorphicDiscriminator/api.yaml b/src/test/resources/examples/enumPolymorphicDiscriminator/api.yaml
index 0759213..27a6d3e 100644
--- a/src/test/resources/examples/enumPolymorphicDiscriminator/api.yaml
+++ b/src/test/resources/examples/enumPolymorphicDiscriminator/api.yaml
@@ -18,7 +18,7 @@ components:
           obj_one_only: '#/components/schemas/ConcreteImplOne'
           obj_two_first: '#/components/schemas/ConcreteImplTwo'
           obj_two_second: '#/components/schemas/ConcreteImplTwo'
-          obj_three: '#/components/schemas/ConcreteImplThree'
+          obj_three: '#/components/schemas/concrete_impl_three'
       properties:
         some_enum:
           $ref: '#/components/schemas/EnumDiscriminator'
@@ -39,7 +39,7 @@ components:
             some_prop:
               type: string
               
-    ConcreteImplThree:
+    concrete_impl_three:
       allOf:
         - $ref: '#/components/schemas/polymorphicEnumDiscriminator'
 
diff --git a/src/test/resources/examples/polymorphicModels/api.yaml b/src/test/resources/examples/polymorphicModels/api.yaml
index b1fa056..ee96efc 100644
--- a/src/test/resources/examples/polymorphicModels/api.yaml
+++ b/src/test/resources/examples/polymorphicModels/api.yaml
@@ -23,7 +23,7 @@ components:
           properties:
             child_one_name:
               type: string
-    PolymorphicTypeTwo:
+    polymorphic_type_two:
       allOf:
         - $ref: "#/components/schemas/PolymorphicSuperType"
         - $ref: "#/components/schemas/AnotherObject"
diff --git a/src/test/resources/examples/polymorphicModels/models/Models.kt b/src/test/resources/examples/polymorphicModels/models/Models.kt
index 28489a4..4d5ba56 100644
--- a/src/test/resources/examples/polymorphicModels/models/Models.kt
+++ b/src/test/resources/examples/polymorphicModels/models/Models.kt
@@ -28,7 +28,7 @@ data class AnotherObject(
     JsonSubTypes.Type(
         value = PolymorphicTypeTwo::class,
         name =
-        "PolymorphicTypeTwo"
+        "polymorphic_type_two"
     )
 )
 sealed class PolymorphicSuperType(
@@ -74,5 +74,5 @@ data class PolymorphicTypeTwo(
 ) : PolymorphicSuperType(firstName, lastName) {
     @get:JsonProperty("generation")
     @get:NotNull
-    override val generation: String = "PolymorphicTypeTwo"
+    override val generation: String = "polymorphic_type_two"
 }
diff --git a/src/test/resources/examples/polymorphicModels/sealed/models/Models.kt b/src/test/resources/examples/polymorphicModels/sealed/models/Models.kt
index 56fa590..7ca84fc 100644
--- a/src/test/resources/examples/polymorphicModels/sealed/models/Models.kt
+++ b/src/test/resources/examples/polymorphicModels/sealed/models/Models.kt
@@ -22,7 +22,7 @@ import kotlin.String
     JsonSubTypes.Type(
         value = PolymorphicTypeTwo::class,
         name =
-        "PolymorphicTypeTwo"
+        "polymorphic_type_two"
     )
 )
 sealed class PolymorphicSuperType(
@@ -68,5 +68,5 @@ data class PolymorphicTypeTwo(
 ) : PolymorphicSuperType(firstName, lastName) {
     @get:JsonProperty("generation")
     @get:NotNull
-    override val generation: String = "PolymorphicTypeTwo"
+    override val generation: String = "polymorphic_type_two"
 }