Skip to content

Commit 7c2ca28

Browse files
committed
Plug PolymorphicFactory into GeneratedCodeConverters Moshi creation
1 parent f120389 commit 7c2ca28

File tree

12 files changed

+397
-10
lines changed

12 files changed

+397
-10
lines changed

gradle-plugin/plugin/src/main/java/com/yelp/codegen/SharedCodegen.kt

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -356,19 +356,32 @@ abstract class SharedCodegen : DefaultCodegen(), CodegenConfig {
356356
.mapNotNull { it[0]["model"] }
357357
.filterIsInstance<CodegenModel>()
358358
.forEach { codegenModel ->
359-
// Ensure that after all the processing done on the CodegenModel.*Vars, hasMore does still make sense
360-
CodegenModelVar.forEachVarAttribute(codegenModel) { _, properties -> properties.fixHasMoreProperty() }
359+
if (
360+
supportsInheritance &&
361+
// Having a single child usually means override of description or attributes that do not change the model
362+
// So we should NOT mark the model with hasChildren
363+
(codegenModel.children?.size ?: 0) > 1
364+
) {
365+
366+
// Codegen does update the children attribute but does not keep hasChildren consistent
367+
codegenModel.hasChildren = true
368+
}
361369

362-
// if (supportsInheritance && true == codegenModel.children?.isNotEmpty()) {
363-
// // Codegen does update the children attribute but does not keep hasChildren consistent
364-
// codegenModel.hasChildren = true
365-
// }
370+
if (codegenModel.parentModel == null) {
371+
codegenModel.allVars?.forEach { it.isInherited = false }
372+
}
366373

367374
if (supportsInheritance && codegenModel.parentModel != null) {
368375
val parentPropertyNames = codegenModel.parentModel.allVars.map { it.name }.toSet()
369376

370377
// Update parentVars (as codegen does not do it while updating the parents)
371-
codegenModel.parentVars?.addAll(codegenModel.parentModel.allVars)
378+
codegenModel.parentVars?.addAll(
379+
codegenModel.parentModel.allVars.map {
380+
val clonedProperty = it.clone()
381+
clonedProperty.isInherited = true
382+
clonedProperty
383+
}
384+
)
372385

373386
decoupleParentProperties(codegenModel)
374387

@@ -396,6 +409,9 @@ abstract class SharedCodegen : DefaultCodegen(), CodegenConfig {
396409
// In order to avoid to consider this model as a model with enums we're re-evaluating it.
397410
codegenModel.hasEnums = codegenModel.vars.any { it.isEnum }
398411
}
412+
413+
// Ensure that after all the processing done on the CodegenModel.*Vars, hasMore does still make sense
414+
CodegenModelVar.forEachVarAttribute(codegenModel) { _, properties -> properties.fixHasMoreProperty() }
399415
}
400416

401417
return postProcessedModels

gradle-plugin/plugin/src/main/resources/kotlin/tools/GeneratedCodeConverters.kt.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import retrofit2.converter.moshi.MoshiConverterFactory
77
object GeneratedCodeConverters {
88
private val moshi = Moshi.Builder()
99
.add(XNullableAdapterFactory())
10+
.add(PolymorphicAdapterFactory())
1011
.add(TypesAdapterFactory())
1112
.build()
1213

samples/junit-tests/junit_tests_specs.json

Lines changed: 135 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,102 @@
11
{
22
"definitions": {
3-
"empty_model": {
3+
"animal": {
4+
"allOf": [
5+
{
6+
"$ref": "#/definitions/living_thing"
7+
},
8+
{
9+
"discriminator": "type",
10+
"properties": {
11+
"classification": {
12+
"enum": [
13+
"amphibian",
14+
"bird",
15+
"fish",
16+
"insect",
17+
"mammal",
18+
"reptile"
19+
],
20+
"type": "string"
21+
},
22+
"type": {
23+
"type": "string"
24+
}
25+
},
26+
"required": [
27+
"type"
28+
],
29+
"type": "object"
30+
}
31+
],
32+
"description": "This is a generic `animal`. According to the value of `type` you might have more information",
33+
"type": "object",
34+
"x-model": "animal"
35+
},
36+
"bird": {
37+
"allOf": [
38+
{
39+
"$ref": "#/definitions/animal"
40+
},
41+
{
42+
"properties": {
43+
"flight_hours": {
44+
"type": "number"
45+
}
46+
}
47+
}
48+
],
49+
"description": "This is a specific type of `animal`: a `bird`",
50+
"title": "Bird",
451
"type": "object",
5-
"x-model": "empty_model"
52+
"x-model": "bird"
53+
},
54+
"cat": {
55+
"allOf": [
56+
{
57+
"$ref": "#/definitions/animal"
58+
},
59+
{
60+
"properties": {
61+
"age": {
62+
"type": "number"
63+
}
64+
},
65+
"type": "object"
66+
}
67+
],
68+
"description": "This is a specific type of `animal`: a `cat`",
69+
"type": "object",
70+
"x-model": "Cat"
71+
},
72+
"dog": {
73+
"allOf": [
74+
{
75+
"$ref": "#/definitions/animal"
76+
},
77+
{
78+
"properties": {
79+
"size": {
80+
"enum": [
81+
"small",
82+
"medium",
83+
"large"
84+
],
85+
"type": "string"
86+
}
87+
},
88+
"required": [
89+
"size"
90+
],
91+
"type": "object"
92+
}
93+
],
94+
"description": "This is a specific type of `animal`: a `dog`",
95+
"type": "object",
96+
"x-model": "dog"
97+
},
98+
"empty_model": {
99+
"type": "object"
6100
},
7101
"format_responses": {
8102
"properties": {
@@ -25,10 +119,24 @@
25119
"type": "object",
26120
"x-model": "format_responses"
27121
},
122+
"living_thing": {
123+
"description": "This is a base class of `animal`. Created to verify that multiple parents are properly dealt with",
124+
"properties": {
125+
"name": {
126+
"type": "string"
127+
}
128+
},
129+
"required": [
130+
"name"
131+
],
132+
"title": "living_thing",
133+
"type": "object"
134+
},
28135
"nested_additional_properties": {
29136
"additionalProperties": {
30137
"$ref": "#/definitions/top_level_map"
31138
},
139+
"title": "xmodel_has_precedence_so_this_will_not_be_used",
32140
"type": "object",
33141
"x-model": "nested_additional_properties"
34142
},
@@ -145,6 +253,15 @@
145253
"type": "object",
146254
"x-model": "reserved_keywords"
147255
},
256+
"snake": {
257+
"allOf": [
258+
{
259+
"$ref": "#/definitions/animal"
260+
}
261+
],
262+
"description": "This is a specific type of `animal`: a `snake`",
263+
"type": "object"
264+
},
148265
"top_level_enum": {
149266
"enum": [
150267
"TOP_LEVEL_VALUE1",
@@ -400,6 +517,22 @@
400517
"version": "1.1.0"
401518
},
402519
"paths": {
520+
"/check_polymorphism": {
521+
"get": {
522+
"operationId": "get_check_polymorphism",
523+
"responses": {
524+
"200": {
525+
"description": "",
526+
"schema": {
527+
"$ref": "#/definitions/animal"
528+
}
529+
}
530+
},
531+
"tags": [
532+
"polymorphism"
533+
]
534+
}
535+
},
403536
"/empty_endpoint": {
404537
"get": {
405538
"operationId": "get_empty_endpoint",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* NOTE: This class is auto generated by the Swagger Gradle Codegen for the following API: JUnit Tests
3+
*
4+
* More info on this tool is available on https://github.com/Yelp/swagger-gradle-codegen
5+
*/
6+
7+
package com.yelp.codegen.generatecodesamples.apis
8+
9+
import com.yelp.codegen.generatecodesamples.models.Animal
10+
import io.reactivex.Single
11+
import retrofit2.http.GET
12+
import retrofit2.http.Headers
13+
14+
@JvmSuppressWildcards
15+
interface PolymorphismApi {
16+
/**
17+
* The endpoint is owned by junittests service owner
18+
*/
19+
@Headers(
20+
"X-Operation-ID: get_check_polymorphism"
21+
)
22+
@GET("/check_polymorphism")
23+
fun getCheckPolymorphism(): Single<Animal>
24+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* NOTE: This class is auto generated by the Swagger Gradle Codegen for the following API: JUnit Tests
3+
*
4+
* More info on this tool is available on https://github.com/Yelp/swagger-gradle-codegen
5+
*/
6+
7+
package com.yelp.codegen.generatecodesamples.models
8+
9+
import com.squareup.moshi.Json
10+
import com.squareup.moshi.JsonClass
11+
import com.yelp.codegen.generatecodesamples.tools.Polymorphic
12+
import com.yelp.codegen.generatecodesamples.tools.optimisticHashCode
13+
14+
/**
15+
* This is a generic `animal`. According to the value of `type` you might have more information
16+
* @property name
17+
* @property classification
18+
* @property type
19+
*/
20+
@JsonClass(generateAdapter = true)
21+
@Polymorphic(
22+
discriminatorField = "type",
23+
discriminatedValues = ["bird", "dog", "snake", "Cat"],
24+
discriminatedClasses = [Bird::class, Dog::class, Snake::class, Cat::class]
25+
)
26+
open class Animal(
27+
@Json(name = "type") @field:Json(name = "type") open var type: String,
28+
@Json(name = "name") @field:Json(name = "name") open override var name: String,
29+
@Json(name = "classification") @field:Json(name = "classification") open var classification: Animal.ClassificationEnum? = null
30+
) {
31+
override fun toString(): String {
32+
return "Animal(" +
33+
"name=$name," +
34+
"classification=$classification," +
35+
"type=$type" +
36+
")"
37+
}
38+
39+
override fun hashCode(): Int {
40+
var resultHashCode = 0
41+
resultHashCode = resultHashCode * 31 + this.name.optimisticHashCode()
42+
resultHashCode = resultHashCode * 31 + this.classification.optimisticHashCode()
43+
resultHashCode = resultHashCode * 31 + this.type.optimisticHashCode()
44+
return resultHashCode
45+
}
46+
47+
override fun equals(other: Any?): Boolean {
48+
return if (this === other) {
49+
true
50+
} else {
51+
other is Animal &&
52+
this.name == other.name &&
53+
this.classification == other.classification &&
54+
this.type == other.type
55+
}
56+
}
57+
58+
/**
59+
* Values: AMPHIBIAN, BIRD, FISH, INSECT, MAMMAL, REPTILE
60+
*/
61+
@JsonClass(generateAdapter = false)
62+
enum class ClassificationEnum(val value: String) {
63+
@Json(name = "amphibian") AMPHIBIAN("amphibian"),
64+
@Json(name = "bird") BIRD("bird"),
65+
@Json(name = "fish") FISH("fish"),
66+
@Json(name = "insect") INSECT("insect"),
67+
@Json(name = "mammal") MAMMAL("mammal"),
68+
@Json(name = "reptile") REPTILE("reptile")
69+
}
70+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* NOTE: This class is auto generated by the Swagger Gradle Codegen for the following API: JUnit Tests
3+
*
4+
* More info on this tool is available on https://github.com/Yelp/swagger-gradle-codegen
5+
*/
6+
7+
package com.yelp.codegen.generatecodesamples.models
8+
9+
import com.squareup.moshi.Json
10+
import com.squareup.moshi.JsonClass
11+
import java.math.BigDecimal
12+
13+
/**
14+
* This is a specific type of `animal`: a `bird`
15+
* @property name
16+
* @property classification
17+
* @property type
18+
* @property flightHours
19+
*/
20+
@JsonClass(generateAdapter = true)
21+
data class Bird(
22+
@Json(name = "name") @field:Json(name = "name") override var name: String,
23+
@Json(name = "type") @field:Json(name = "type") override var type: String,
24+
@Json(name = "flight_hours") @field:Json(name = "flight_hours") var flightHours: BigDecimal? = null,
25+
@Json(name = "classification") @field:Json(name = "classification") override var classification: Animal.ClassificationEnum? = null
26+
) : Animal(name = name, classification = classification, type = type)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* NOTE: This class is auto generated by the Swagger Gradle Codegen for the following API: JUnit Tests
3+
*
4+
* More info on this tool is available on https://github.com/Yelp/swagger-gradle-codegen
5+
*/
6+
7+
package com.yelp.codegen.generatecodesamples.models
8+
9+
import com.squareup.moshi.Json
10+
import com.squareup.moshi.JsonClass
11+
import java.math.BigDecimal
12+
13+
/**
14+
* This is a specific type of `animal`: a `cat`
15+
* @property name
16+
* @property classification
17+
* @property type
18+
* @property age
19+
*/
20+
@JsonClass(generateAdapter = true)
21+
data class Cat(
22+
@Json(name = "name") @field:Json(name = "name") override var name: String,
23+
@Json(name = "type") @field:Json(name = "type") override var type: String,
24+
@Json(name = "age") @field:Json(name = "age") var age: BigDecimal? = null,
25+
@Json(name = "classification") @field:Json(name = "classification") override var classification: Animal.ClassificationEnum? = null
26+
) : Animal(name = name, classification = classification, type = type)

0 commit comments

Comments
 (0)