11package com .algolia .codegen .utils ;
22
3+ import com .algolia .codegen .AlgoliaSwiftGenerator ;
34import java .util .*;
45import java .util .function .Function ;
56import org .openapitools .codegen .*;
@@ -43,18 +44,19 @@ private static void setHasChildGeneric(IJsonSchemaValidationProperties property)
4344 * x-has-child-generic
4445 */
4546 private static boolean hasGeneric (IJsonSchemaValidationProperties property ) {
46- if (property instanceof CodegenModel ) {
47- return (
48- (boolean ) ((CodegenModel ) property ).vendorExtensions .getOrDefault ("x-propagated-generic" , false ) ||
49- (boolean ) ((CodegenModel ) property ).vendorExtensions .getOrDefault ("x-has-child-generic" , false )
50- );
51- } else if (property instanceof CodegenProperty ) {
52- return (
53- (boolean ) ((CodegenProperty ) property ).vendorExtensions .getOrDefault ("x-propagated-generic" , false ) ||
54- (boolean ) ((CodegenProperty ) property ).vendorExtensions .getOrDefault ("x-has-child-generic" , false )
55- );
47+ Map <String , Object > vendorExtensions ;
48+ if (property instanceof CodegenModel model ) {
49+ vendorExtensions = model .vendorExtensions ;
50+ } else if (property instanceof CodegenProperty prop ) {
51+ vendorExtensions = prop .vendorExtensions ;
52+ } else {
53+ return false ;
5654 }
57- return false ;
55+ return (
56+ (boolean ) vendorExtensions .getOrDefault ("x-propagated-generic" , false ) ||
57+ (boolean ) vendorExtensions .getOrDefault ("x-has-child-generic" , false ) ||
58+ (boolean ) vendorExtensions .getOrDefault ("x-is-generic" , false )
59+ );
5860 }
5961
6062 private static CodegenModel propertyToModel (Map <String , CodegenModel > models , CodegenProperty prop ) {
@@ -78,16 +80,13 @@ private static boolean markPropagatedGeneric(
7880 }
7981 // if items itself isn't generic, we recurse on its items and properties until we reach the
8082 // end or find a generic property
81- if (
82- items != null &&
83- ((boolean ) items .vendorExtensions .getOrDefault ("x-is-generic" , false ) || markPropagatedGeneric (items , getVar , skipOneOf ))
84- ) {
83+ if (items != null && (hasGeneric (items ) || markPropagatedGeneric (items , getVar , skipOneOf ))) {
8584 setPropagatedGeneric (model );
8685 return true ;
8786 }
8887 for (CodegenProperty variable : getVar .apply (model )) {
8988 // same thing for the variable, if it's not a generic, we recurse on it until we find one
90- if (( boolean ) variable . vendorExtensions . getOrDefault ( "x-is-generic" , false ) || markPropagatedGeneric (variable , getVar , skipOneOf )) {
89+ if (hasGeneric ( items ) || markPropagatedGeneric (variable , getVar , skipOneOf )) {
9190 setPropagatedGeneric (model );
9291 return true ;
9392 }
@@ -122,12 +121,17 @@ private static boolean propagateGenericRecursive(
122121 return false ;
123122 }
124123
125- private static void setGenericToComposedSchema (Map <String , CodegenModel > models , List <CodegenProperty > composedSchemas ) {
124+ private static void setGenericToComposedSchema (
125+ Map <String , CodegenModel > models ,
126+ CodegenModel model ,
127+ List <CodegenProperty > composedSchemas
128+ ) {
126129 if (composedSchemas == null ) {
127130 return ;
128131 }
129132 for (CodegenProperty prop : composedSchemas ) {
130- if (hasGeneric (propertyToModel (models , prop ))) {
133+ if (hasGeneric (prop ) || hasGeneric (propertyToModel (models , prop ))) {
134+ setHasChildGeneric (model );
131135 setHasChildGeneric (prop );
132136 }
133137 }
@@ -138,62 +142,86 @@ private static void propagateToComposedSchema(Map<String, CodegenModel> models,
138142 if (composedSchemas == null ) {
139143 return ;
140144 }
141- setGenericToComposedSchema (models , composedSchemas .getOneOf ());
142- setGenericToComposedSchema (models , composedSchemas .getAllOf ());
143- setGenericToComposedSchema (models , composedSchemas .getAnyOf ());
145+ setGenericToComposedSchema (models , model , composedSchemas .getOneOf ());
146+ setGenericToComposedSchema (models , model , composedSchemas .getAllOf ());
147+ setGenericToComposedSchema (models , model , composedSchemas .getAnyOf ());
144148 }
145149
146- private static Map <String , CodegenModel > convertToMap (Map <String , ModelsMap > models ) {
150+ private static Map <String , CodegenModel > convertToMap (String language , String client , Map <String , ModelsMap > models ) {
147151 Map <String , CodegenModel > modelsMap = new TreeMap <>(String .CASE_INSENSITIVE_ORDER );
148152 for (ModelsMap modelMap : models .values ()) {
149153 // modelContainers always have 1 and only 1 model in our specs
150154 CodegenModel model = modelMap .getModels ().get (0 ).getModel ();
151- modelsMap .put (model .name , model );
155+ String modelName = model .name ;
156+ if (language .equals ("swift" ) && !client .equals ("search" )) {
157+ modelName = AlgoliaSwiftGenerator .prefixReservedModelName (modelName , client );
158+ }
159+ modelsMap .put (modelName , model );
152160 }
153161 return modelsMap ;
154162 }
155163
156- private static Map <String , CodegenModel > convertToMap (List <ModelMap > models ) {
164+ private static Map <String , CodegenModel > convertToMap (String language , String client , List <ModelMap > models ) {
157165 Map <String , CodegenModel > modelsMap = new TreeMap <>(String .CASE_INSENSITIVE_ORDER );
158166 for (ModelMap modelMap : models ) {
159167 CodegenModel model = modelMap .getModel ();
160- modelsMap .put (model .name , model );
168+ String modelName = model .name ;
169+ if (language .equals ("swift" ) && !client .equals ("search" )) {
170+ modelName = AlgoliaSwiftGenerator .prefixReservedModelName (modelName , client );
171+ }
172+ modelsMap .put (modelName , model );
161173 }
162174 return modelsMap ;
163175 }
164176
165177 /**
166178 * Models and their members will be marked with either x-propagated-generic or x-has-child-generic
167179 */
168- public static void propagateGenericsToModels (Map <String , ModelsMap > modelsMap , boolean skipOneOf ) {
180+ public static void propagateGenericsToModels (String language , String client , Map <String , ModelsMap > modelsMap , boolean skipOneOf ) {
169181 // We propagate generics in two phases:
170182 // 1. We mark the direct parent of the generic model to replace it with T
171183 // 2. We tell each parent with generic properties to pass that generic type all the way down
172184
173- Map <String , CodegenModel > models = convertToMap (modelsMap );
185+ Map <String , CodegenModel > models = convertToMap (language , client , modelsMap );
174186
175- for (CodegenModel model : models .values ()) {
176- markPropagatedGeneric (model , m -> m .getVars (), skipOneOf );
177- markPropagatedGeneric (model , m -> m .getRequiredVars (), skipOneOf );
178- }
187+ // we don't know in which order the model will come, so we iterate multiple times to make sure
188+ // models at any depth are propagated
189+ for (int i = 0 ; i < 5 ; i ++) {
190+ for (CodegenModel model : models .values ()) {
191+ markPropagatedGeneric (model , m -> m .getVars (), skipOneOf );
192+ markPropagatedGeneric (model , m -> m .getRequiredVars (), skipOneOf );
193+ }
179194
180- for (CodegenModel model : models .values ()) {
181- propagateGenericRecursive (models , model , m -> m .getVars ());
182- propagateGenericRecursive (models , model , m -> m .getRequiredVars ());
183- }
195+ for (CodegenModel model : models .values ()) {
196+ propagateGenericRecursive (models , model , m -> m .getVars ());
197+ propagateGenericRecursive (models , model , m -> m .getRequiredVars ());
198+ }
184199
185- for (CodegenModel model : models .values ()) {
186- propagateToComposedSchema (models , model );
200+ for (CodegenModel model : models .values ()) {
201+ propagateToComposedSchema (models , model );
202+ }
187203 }
188204 }
189205
190206 public static void propagateGenericsToModels (Map <String , ModelsMap > modelsMap ) {
191207 propagateGenericsToModels (modelsMap , false );
192208 }
193209
210+ public static void propagateGenericsToModels (Map <String , ModelsMap > modelsMap , boolean skipOneOf ) {
211+ propagateGenericsToModels ("dontcare" , "dontcare" , modelsMap , false );
212+ }
213+
214+ public static void propagateGenericsToModels (String language , String client , Map <String , ModelsMap > modelsMap ) {
215+ propagateGenericsToModels (language , client , modelsMap , false );
216+ }
217+
194218 /** Mark operations with a generic return type with x-is-generic */
195219 public static void propagateGenericsToOperations (OperationsMap operations , List <ModelMap > allModels ) {
196- Map <String , CodegenModel > models = convertToMap (allModels );
220+ propagateGenericsToOperations ("dontcare" , "dontcare" , operations , allModels );
221+ }
222+
223+ public static void propagateGenericsToOperations (String language , String client , OperationsMap operations , List <ModelMap > allModels ) {
224+ Map <String , CodegenModel > models = convertToMap (language , client , allModels );
197225 for (CodegenOperation ope : operations .getOperations ().getOperation ()) {
198226 if (ope .returnType == null ) {
199227 continue ;
0 commit comments