Skip to content

Commit 7e1ec6d

Browse files
committed
GH-230 Cache processed types in properties to avoid infinite recursion when going through createEmbeddedTypeDescription (Fix #230)
1 parent 3d15957 commit 7e1ec6d

File tree

2 files changed

+24
-12
lines changed
  • examples/javalin-gradle-kotlin/src/main/java/io/javalin/openapi/plugin/test
  • openapi-specification/src/main/kotlin/io/javalin/openapi/experimental/processor/generators

2 files changed

+24
-12
lines changed

examples/javalin-gradle-kotlin/src/main/java/io/javalin/openapi/plugin/test/JavalinTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,9 @@ public static String getStatic() {
396396
}
397397

398398
// by default nullable fields are not required, but we can force it
399-
@OpenApiRequired
400-
public String getNullableIsRequired() {
401-
return "required";
399+
//@OpenApiRequired
400+
public JsonSchemaEntity getNullableIsRequired() {
401+
return null;
402402
}
403403

404404
}

openapi-specification/src/main/kotlin/io/javalin/openapi/experimental/processor/generators/TypeSchemaGenerator.kt

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ data class ResultScheme(
5151

5252
class TypeSchemaGenerator(val context: AnnotationProcessorContext) {
5353

54+
// The cache helps to avoid processing the same property multiple times & prevent infinite recursion
55+
// ~ https://github.com/javalin/javalin-openapi/issues/230
56+
private val processedProperties = mutableMapOf<Property, ResultScheme>()
57+
5458
fun createTypeSchema(
5559
type: ClassDefinition,
5660
inlineRefs: Boolean = false,
@@ -102,15 +106,23 @@ class TypeSchemaGenerator(val context: AnnotationProcessorContext) {
102106
val properties = type.findAllProperties(requireNonNulls)
103107

104108
properties.forEach { property ->
105-
val (propertySchema, refs) = createEmbeddedTypeDescription(
106-
type = property.type,
107-
inlineRefs = inlineRefs,
108-
requiresNonNulls = requireNonNulls,
109-
composition = property.composition,
110-
extra = property.extra
111-
)
112-
propertiesObject.add(property.name, propertySchema)
113-
references.addAll(refs)
109+
val result =
110+
when {
111+
processedProperties.contains(property) ->
112+
processedProperties[property]!!
113+
else ->
114+
createEmbeddedTypeDescription(
115+
type = property.type,
116+
inlineRefs = inlineRefs,
117+
requiresNonNulls = requireNonNulls,
118+
composition = property.composition,
119+
extra = property.extra
120+
).also {
121+
processedProperties[property] = it
122+
}
123+
}
124+
propertiesObject.add(property.name, result.json)
125+
references.addAll(result.references)
114126
}
115127

116128
if (properties.any { it.required }) {

0 commit comments

Comments
 (0)