@@ -12,6 +12,18 @@ private OneOf() {
1212 }
1313
1414 public static void updateModelsOneOf (Map <String , ModelsMap > models , String modelPackage ) {
15+ // first, propagate the discriminator of allOf to the parent
16+ for (ModelsMap modelContainer : models .values ()) {
17+ var model = modelContainer .getModels ().get (0 ).getModel ();
18+ if (model .getComposedSchemas () != null && model .getComposedSchemas ().getAllOf () != null ) {
19+ for (CodegenProperty prop : model .getComposedSchemas ().getAllOf ()) {
20+ if (prop .vendorExtensions .containsKey ("x-discriminator-fields" )) {
21+ model .vendorExtensions .put ("x-discriminator-fields" , prop .vendorExtensions .get ("x-discriminator-fields" ));
22+ }
23+ }
24+ }
25+ }
26+
1527 for (ModelsMap modelContainer : models .values ()) {
1628 // modelContainers always have 1 and only 1 model in our specs
1729 var model = modelContainer .getModels ().get (0 ).getModel ();
@@ -63,7 +75,6 @@ private static void markOneOfChildren(Map<String, ModelsMap> models, CodegenMode
6375 markCompounds (models , oneOf , oneOfModel , model );
6476 oneOfList .add (oneOfModel );
6577 }
66- oneOfList .sort (comparator ); // have fields with "discriminators" in the start of the list
6778 model .vendorExtensions .put ("x-one-of-list" , oneOfList );
6879 }
6980
@@ -86,8 +97,13 @@ public static void markCompounds(Map<String, ModelsMap> models, String oneOf, Ma
8697 //noinspection unchecked
8798 var values = (List <String >) compoundModel .vendorExtensions .get ("x-discriminator-fields" );
8899 if (values != null ) {
89- List <Map <String , String >> newValues = values .stream ().map (value -> Collections .singletonMap ("field" , value )).toList ();
90- oneOfModel .put ("discriminators" , newValues );
100+ oneOfModel .put ("x-discriminator-fields" , values );
101+ // find the matching composed schema and assign the discriminator
102+ for (var m : model .getComposedSchemas ().getOneOf ()) {
103+ if (m .openApiType .equals (compoundModel .classname )) {
104+ m .vendorExtensions .put ("x-discriminator-fields" , values );
105+ }
106+ }
91107 }
92108 }
93109
@@ -104,29 +120,6 @@ private static boolean isNumberType(String typeName) {
104120 return typeName .equals ("Int" ) || typeName .equals ("Double" ) || typeName .equals ("Long" );
105121 }
106122
107- public static final Comparator <Map <String , Object >> comparator = (mapA , mapB ) -> {
108- boolean hasDiscriminatorA = mapA .containsKey ("discriminators" );
109- boolean hasDiscriminatorB = mapB .containsKey ("discriminators" );
110- // Maps with "discriminators" come first
111- if (hasDiscriminatorA && !hasDiscriminatorB ) {
112- return -1 ;
113- } else if (!hasDiscriminatorA && hasDiscriminatorB ) {
114- return 1 ;
115- } else {
116- // If both maps have or don't have "discriminators," compare their list lengths
117- if (hasDiscriminatorA && hasDiscriminatorB ) {
118- List <?> discriminatorsA = (List <?>) mapA .get ("discriminators" );
119- List <?> discriminatorsB = (List <?>) mapB .get ("discriminators" );
120-
121- // Compare the lengths of the lists
122- return discriminatorsB .size () - discriminatorsA .size ();
123- }
124-
125- // If the lengths are the same or both maps don't have "discriminators," return 0
126- return 0 ;
127- }
128- };
129-
130123 /**
131124 * Add metadata about oneOfs models (e.g., if it has at least one model, if it has more than one
132125 * array-subtype, etc.)
@@ -139,6 +132,7 @@ public static void addOneOfMetadata(Map<String, ModelsMap> models) {
139132 if (isMultiArrayOneOfs (oneOfs )) model .vendorExtensions .put ("x-is-multi-array" , true );
140133 if (isMultiMapOneOfs (oneOfs )) model .vendorExtensions .put ("x-is-multi-map" , true );
141134 if (hasAtModelOrEnum (oneOfs )) model .vendorExtensions .put ("x-has-model" , true );
135+ if (hasDiscriminators (oneOfs )) model .vendorExtensions .put ("x-has-discriminator" , true );
142136 markOneOfModels (oneOfs );
143137 sortOneOfs (oneOfs );
144138 }
@@ -178,6 +172,14 @@ private static boolean hasAtModelOrEnum(List<CodegenProperty> oneOfs) {
178172 return false ;
179173 }
180174
175+ /** Return true if at least one oneOf has discriminators */
176+ private static boolean hasDiscriminators (List <CodegenProperty > oneOfs ) {
177+ for (var prop : oneOfs ) {
178+ if (prop .vendorExtensions .containsKey ("x-discriminator-fields" )) return true ;
179+ }
180+ return false ;
181+ }
182+
181183 /** Mark oneOf models */
182184 private static void markOneOfModels (List <CodegenProperty > oneOfs ) {
183185 for (var prop : oneOfs ) {
@@ -201,7 +203,7 @@ private static void sortOneOfs(List<CodegenProperty> oneOfs) {
201203 return 1 ;
202204 } else if (hasDiscriminatorA && hasDiscriminatorB ) {
203205 List <?> discriminatorsA = (List <?>) propA .vendorExtensions .get ("x-discriminator-fields" );
204- List <?> discriminatorsB = (List <?>) propA .vendorExtensions .get ("x-discriminator-fields" );
206+ List <?> discriminatorsB = (List <?>) propB .vendorExtensions .get ("x-discriminator-fields" );
205207 return discriminatorsB .size () - discriminatorsA .size ();
206208 } else {
207209 return 0 ;
0 commit comments