96069c273c071b96d3594b484055f0c32913a6f1
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-generator-impl / src / main / java / org / opendaylight / controller / sal / binding / yang / types / TypeProviderImpl.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.sal.binding.yang.types;
9
10 import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
11 import org.opendaylight.controller.binding.generator.util.Types;
12 import org.opendaylight.controller.binding.generator.util.generated.type.builder.EnumerationBuilderImpl;
13 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
14 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
15 import org.opendaylight.controller.sal.binding.model.api.Enumeration;
16 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
17 import org.opendaylight.controller.sal.binding.model.api.Type;
18 import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;
19 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
20 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
21 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
22 import org.opendaylight.controller.yang.common.QName;
23 import org.opendaylight.controller.yang.model.api.*;
24 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
25 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
26 import org.opendaylight.controller.yang.model.api.type.IdentityrefTypeDefinition;
27 import org.opendaylight.controller.yang.model.api.type.LeafrefTypeDefinition;
28 import org.opendaylight.controller.yang.model.api.type.UnionTypeDefinition;
29 import org.opendaylight.controller.yang.model.util.ExtendedType;
30
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35
36 import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
37 import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.*;
38
39 public final class TypeProviderImpl implements TypeProvider {
40
41     private final SchemaContext schemaContext;
42     private Map<String, Map<String, Type>> genTypeDefsContextMap;
43     private final Map<SchemaPath, Type> referencedTypes;
44
45     public TypeProviderImpl(final SchemaContext schemaContext) {
46         if (schemaContext == null) {
47             throw new IllegalArgumentException("Schema Context cannot be null!");
48         }
49
50         this.schemaContext = schemaContext;
51         this.genTypeDefsContextMap = new HashMap<>();
52         this.referencedTypes = new HashMap<>();
53         resolveTypeDefsFromContext();
54     }
55
56     public void putReferencedType(final SchemaPath refTypePath,
57                                   final Type refType) {
58         if (refTypePath == null) {
59             throw new IllegalArgumentException("Path reference of " +
60                     "Enumeration Type Definition cannot be NULL!");
61         }
62
63         if (refType == null) {
64             throw new IllegalArgumentException("Reference to Enumeration " +
65                     "Type cannot be NULL!");
66         }
67         referencedTypes.put(refTypePath, refType);
68     }
69
70     /*
71      * (non-Javadoc)
72      *
73      * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider#
74      * javaTypeForYangType(java.lang.String)
75      */
76     @Override
77     public Type javaTypeForYangType(String type) {
78         Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
79                 .javaTypeForYangType(type);
80         return t;
81     }
82
83     @Override
84     public Type javaTypeForSchemaDefinitionType(
85             final TypeDefinition<?> typeDefinition) {
86         Type returnType = null;
87         if (typeDefinition == null) {
88             throw new IllegalArgumentException("Type Definition cannot be " +
89                     "NULL!");
90         }
91         if (typeDefinition.getQName() == null) {
92             throw new IllegalArgumentException("Type Definition cannot have " +
93                     "non specified QName (QName cannot be NULL!)");
94         }
95         if (typeDefinition.getQName().getLocalName() == null) {
96             throw new IllegalArgumentException("Type Definitions Local Name " +
97                     "cannot be NULL!");
98         }
99         final String typedefName = typeDefinition.getQName().getLocalName();
100         if (typeDefinition instanceof ExtendedType) {
101             final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
102
103             if (baseTypeDef instanceof LeafrefTypeDefinition) {
104                 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) baseTypeDef;
105                 returnType = provideTypeForLeafref(leafref);
106             } else if (baseTypeDef instanceof IdentityrefTypeDefinition) {
107                 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition)typeDefinition;
108                 returnType = returnTypeForIdentityref(idref);
109             } else if (baseTypeDef instanceof EnumTypeDefinition) {
110                 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef;
111                 returnType = resolveEnumFromTypeDefinition(enumTypeDef,
112                         typedefName);
113             } else {
114                 final Module module = findParentModuleForTypeDefinition(schemaContext,
115                         typeDefinition);
116                 if (module != null) {
117                     final Map<String, Type> genTOs = genTypeDefsContextMap
118                             .get(module.getName());
119                     if (genTOs != null) {
120                         returnType = genTOs.get(typedefName);
121                     }
122                     if (returnType == null) {
123                         returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
124                                 .javaTypeForSchemaDefinitionType(baseTypeDef);
125                     }
126                 }
127             }
128         } else {
129             if (typeDefinition instanceof LeafrefTypeDefinition) {
130                 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
131                 returnType = provideTypeForLeafref(leafref);
132             } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
133                 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition)typeDefinition;
134                 returnType = returnTypeForIdentityref(idref);
135             } else {
136                 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
137                         .javaTypeForSchemaDefinitionType(typeDefinition);
138             }
139         }
140         //TODO: add throw exception when we will be able to resolve ALL yang
141         // types!
142 //        if (returnType == null) {
143 //            throw new IllegalArgumentException("Type Provider can't resolve " +
144 //                    "type for specified Type Definition " + typedefName);
145 //        }
146         return returnType;
147     }
148     
149     private Type returnTypeForIdentityref(IdentityrefTypeDefinition idref) {
150         QName baseIdQName = idref.getIdentity();
151         Module module = schemaContext.findModuleByNamespace(baseIdQName.getNamespace());
152         IdentitySchemaNode identity = null;
153         for(IdentitySchemaNode id : module.getIdentities()) {
154             if(id.getQName().equals(baseIdQName)) {
155                 identity = id;
156             }
157         }
158         if(identity == null) {
159             throw new IllegalArgumentException("Target identity '" + baseIdQName + "' do not exists");
160         }
161
162         final String basePackageName = moduleNamespaceToPackageName(module);
163         final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
164         final String genTypeName = parseToClassName(identity.getQName().getLocalName());
165
166         Type baseType = Types.typeForClass(Class.class);
167         Type paramType = Types.wildcardTypeFor(packageName, genTypeName);
168         Type returnType = Types.parameterizedTypeFor(baseType, paramType);
169         return returnType;
170     }
171
172     public Type generatedTypeForExtendedDefinitionType(
173             final TypeDefinition<?> typeDefinition) {
174         Type returnType = null;
175         if (typeDefinition == null) {
176             throw new IllegalArgumentException("Type Definition cannot be " +
177                     "NULL!");
178         }
179         if (typeDefinition.getQName() == null) {
180             throw new IllegalArgumentException("Type Definition cannot have " +
181                     "non specified QName (QName cannot be NULL!)");
182         }
183         if (typeDefinition.getQName() == null) {
184             throw new IllegalArgumentException("Type Definitions Local Name " +
185                     "cannot be NULL!");
186         }
187
188         final String typedefName = typeDefinition.getQName().getLocalName();
189         if (typeDefinition instanceof ExtendedType) {
190             final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
191
192             if (!(baseTypeDef instanceof LeafrefTypeDefinition)
193                     && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
194                 final Module module = findParentModuleForTypeDefinition(schemaContext,
195                         typeDefinition);
196
197                 if (module != null) {
198                     final Map<String, Type> genTOs = genTypeDefsContextMap
199                             .get(module.getName());
200                     if (genTOs != null) {
201                         returnType = genTOs.get(typedefName);
202                     }
203                 }
204             }
205         }
206         return returnType;
207     }
208
209     private TypeDefinition<?> baseTypeDefForExtendedType(
210             final TypeDefinition<?> extendTypeDef) {
211         if (extendTypeDef == null) {
212             throw new IllegalArgumentException("Type Definiition reference " +
213                     "cannot be NULL!");
214         }
215         final TypeDefinition<?> baseTypeDef = extendTypeDef.getBaseType();
216         if (baseTypeDef instanceof ExtendedType) {
217             return baseTypeDefForExtendedType(baseTypeDef);
218         } else {
219             return baseTypeDef;
220         }
221
222     }
223
224     public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) {
225         Type returnType = null;
226         if (leafrefType == null) {
227             throw new IllegalArgumentException("Leafref Type Definition " +
228                     "reference cannot be NULL!");
229         }
230
231         if (leafrefType.getPathStatement() == null) {
232             throw new IllegalArgumentException("The Path Statement for " +
233                     "Leafref Type Definition cannot be NULL!");
234         }
235
236         final RevisionAwareXPath xpath = leafrefType.getPathStatement();
237         final String strXPath = xpath.toString();
238
239         if (strXPath != null) {
240             if (strXPath.matches(".*//[.* | .*//].*")) {
241                 returnType = Types.typeForClass(Object.class);
242             } else {
243                 final Module module = findParentModuleForTypeDefinition(schemaContext, leafrefType);
244                 if (module != null) {
245                     final DataSchemaNode dataNode;
246                     if (xpath.isAbsolute()) {
247                         dataNode = findDataSchemaNode(schemaContext, module,
248                                 xpath);
249                     } else {
250                         dataNode = findDataSchemaNodeForRelativeXPath(schemaContext,
251                                 module, leafrefType, xpath);
252                     }
253
254                     if (leafContainsEnumDefinition(dataNode)) {
255                         returnType = referencedTypes.get(dataNode.getPath());
256                     } else if (leafListContainsEnumDefinition(dataNode)) {
257                         returnType = Types.listTypeFor(referencedTypes.get(
258                                 dataNode.getPath()));
259                     } else {
260                         returnType = resolveTypeFromDataSchemaNode(dataNode);
261                     }
262                 }
263             }
264         }
265         return returnType;
266     }
267
268     private boolean leafContainsEnumDefinition(final DataSchemaNode dataNode) {
269         if (dataNode instanceof LeafSchemaNode) {
270             final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
271             if (leaf.getType() instanceof EnumTypeDefinition) {
272                 return true;
273             }
274         }
275         return false;
276     }
277
278     private boolean leafListContainsEnumDefinition(
279             final DataSchemaNode dataNode) {
280         if (dataNode instanceof LeafListSchemaNode) {
281             final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
282             if (leafList.getType() instanceof EnumTypeDefinition) {
283                 return true;
284             }
285         }
286         return false;
287     }
288
289     private Enumeration resolveEnumFromTypeDefinition(
290             final EnumTypeDefinition enumTypeDef, final String enumName) {
291         if (enumTypeDef == null) {
292             throw new IllegalArgumentException("EnumTypeDefinition reference " +
293                     "cannot be NULL!");
294         }
295         if (enumTypeDef.getValues() == null) {
296             throw new IllegalArgumentException("EnumTypeDefinition MUST " +
297                     "contain at least ONE value definition!");
298         }
299         if (enumTypeDef.getQName() == null) {
300             throw new IllegalArgumentException("EnumTypeDefinition MUST " +
301                     "contain NON-NULL QName!");
302         }
303         if (enumTypeDef.getQName().getLocalName() == null) {
304             throw new IllegalArgumentException("Local Name in " +
305                     "EnumTypeDefinition QName cannot be NULL!");
306         }
307
308         final String enumerationName = parseToClassName(enumName);
309
310         Module module = findParentModuleForTypeDefinition(schemaContext, enumTypeDef);
311         final String basePackageName = moduleNamespaceToPackageName(module);
312
313         final EnumBuilder enumBuilder = new EnumerationBuilderImpl(
314                 basePackageName, enumerationName);
315         updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder);
316         return enumBuilder.toInstance(null);
317     }
318
319     private EnumBuilder resolveInnerEnumFromTypeDefinition(
320             final EnumTypeDefinition enumTypeDef, final String enumName,
321             final GeneratedTypeBuilder typeBuilder) {
322         if (enumTypeDef == null) {
323             throw new IllegalArgumentException("EnumTypeDefinition reference " +
324                     "cannot be NULL!");
325         }
326         if (enumTypeDef.getValues() == null) {
327             throw new IllegalArgumentException("EnumTypeDefinition MUST " +
328                     "contain at least ONE value definition!");
329         }
330         if (enumTypeDef.getQName() == null) {
331             throw new IllegalArgumentException("EnumTypeDefinition MUST " +
332                     "contain NON-NULL QName!");
333         }
334         if (enumTypeDef.getQName().getLocalName() == null) {
335             throw new IllegalArgumentException("Local Name in " +
336                     "EnumTypeDefinition QName cannot be NULL!");
337         }
338         if (typeBuilder == null) {
339             throw new IllegalArgumentException("Generated Type Builder " +
340                     "reference cannot be NULL!");
341         }
342
343         final String enumerationName = parseToClassName(enumName);
344         final EnumBuilder enumBuilder = typeBuilder
345                 .addEnumeration(enumerationName);
346
347         updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder);
348
349         return enumBuilder;
350     }
351
352     private void updateEnumPairsFromEnumTypeDef(
353             final EnumTypeDefinition enumTypeDef,
354             final EnumBuilder enumBuilder) {
355         if (enumBuilder != null) {
356             final List<EnumPair> enums = enumTypeDef.getValues();
357             if (enums != null) {
358                 int listIndex = 0;
359                 for (final EnumPair enumPair : enums) {
360                     if (enumPair != null) {
361                         final String enumPairName = parseToClassName(enumPair
362                                 .getName());
363                         Integer enumPairValue = enumPair.getValue();
364
365                         if (enumPairValue == null) {
366                             enumPairValue = listIndex;
367                         }
368                         enumBuilder.addValue(enumPairName, enumPairValue);
369                         listIndex++;
370                     }
371                 }
372             }
373         }
374     }
375
376     private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) {
377         Type returnType = null;
378         if (dataNode != null) {
379             if (dataNode instanceof LeafSchemaNode) {
380                 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
381                 returnType = javaTypeForSchemaDefinitionType(leaf.getType());
382             } else if (dataNode instanceof LeafListSchemaNode) {
383                 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
384                 returnType = javaTypeForSchemaDefinitionType(leafList.getType());
385             }
386         }
387         return returnType;
388     }
389
390     private void resolveTypeDefsFromContext() {
391         final Set<Module> modules = schemaContext.getModules();
392         if (modules == null) {
393             throw new IllegalArgumentException("Sef of Modules cannot be " +
394                     "NULL!");
395         }
396         for (final Module module : modules) {
397             if (module == null) {
398                 continue;
399             }
400             final String moduleName = module.getName();
401             final String basePackageName = moduleNamespaceToPackageName(module);
402
403             final Set<TypeDefinition<?>> typeDefinitions = module
404                     .getTypeDefinitions();
405
406             final Map<String, Type> typeMap = new HashMap<>();
407             genTypeDefsContextMap.put(moduleName, typeMap);
408
409             if ((typeDefinitions != null) && (basePackageName != null)) {
410                 for (final TypeDefinition<?> typedef : typeDefinitions) {
411                     typedefToGeneratedType(basePackageName, moduleName, typedef);
412                 }
413                 final List<ExtendedType> extUnions = UnionDependencySort
414                         .sort(typeDefinitions);
415                 for (final ExtendedType extUnionType : extUnions) {
416                     addUnionGeneratedTypeDefinition(basePackageName, extUnionType);
417                 }
418             }
419         }
420     }
421
422     private Type typedefToGeneratedType(final String basePackageName,
423                                         final String moduleName, final TypeDefinition<?> typedef) {
424         if ((basePackageName != null) && (moduleName != null)
425                 && (typedef != null) && (typedef.getQName() != null)) {
426
427
428             final String typedefName = typedef.getQName().getLocalName();
429             final TypeDefinition<?> baseTypeDefinition = baseTypeDefForExtendedType(typedef);
430             if (!(baseTypeDefinition instanceof LeafrefTypeDefinition)
431                     && !(baseTypeDefinition instanceof IdentityrefTypeDefinition)) {
432                 Type returnType;
433                 if (baseTypeDefinition instanceof EnumTypeDefinition) {
434                     final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDefinition;
435                     returnType = resolveEnumFromTypeDefinition(enumTypeDef,
436                             typedefName);
437
438                 } else {
439                     final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
440                             .javaTypeForSchemaDefinitionType(baseTypeDefinition);
441
442                     returnType = wrapJavaTypeIntoTO(basePackageName, typedef,
443                             javaType);
444                 }
445                 if (returnType != null) {
446                     final Map<String, Type> typeMap = genTypeDefsContextMap.get
447                             (moduleName);
448                     if (typeMap != null) {
449                         typeMap.put(typedefName, returnType);
450                     }
451                     return returnType;
452                 }
453             }
454         }
455         return null;
456     }
457
458     private GeneratedTransferObject wrapJavaTypeIntoTO(
459             final String basePackageName, final TypeDefinition<?> typedef,
460             final Type javaType) {
461         if (javaType != null) {
462             final String typedefName = typedef.getQName().getLocalName();
463             final String propertyName = parseToValidParamName(typedefName);
464
465             final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(
466                     basePackageName, typedef);
467
468             final GeneratedPropertyBuilder genPropBuilder = genTOBuilder
469                     .addProperty(propertyName);
470
471             genPropBuilder.addReturnType(javaType);
472             genTOBuilder.addEqualsIdentity(genPropBuilder);
473             genTOBuilder.addHashIdentity(genPropBuilder);
474             genTOBuilder.addToStringProperty(genPropBuilder);
475             return genTOBuilder.toInstance();
476         }
477         return null;
478     }
479
480     private void addUnionGeneratedTypeDefinition(final String basePackageName,
481                                                  final TypeDefinition<?> typedef) {
482         if (basePackageName == null) {
483             throw new IllegalArgumentException("Base Package Name cannot be " +
484                     "NULL!");
485         }
486         if (typedef == null) {
487             throw new IllegalArgumentException("Type Definition cannot be " +
488                     "NULL!");
489         }
490         if (typedef.getQName() == null) {
491             throw new IllegalArgumentException("Type Definition cannot have " +
492                     "non specified QName (QName cannot be NULL!)");
493         }
494
495         final TypeDefinition<?> baseTypeDefinition = typedef.getBaseType();
496         if ((baseTypeDefinition != null)
497                 && (baseTypeDefinition instanceof UnionTypeDefinition)) {
498             final UnionTypeDefinition unionTypeDef = (UnionTypeDefinition) baseTypeDefinition;
499             final List<TypeDefinition<?>> unionTypes = unionTypeDef
500                     .getTypes();
501             final Module parentModule = findParentModuleForTypeDefinition(schemaContext,
502                     typedef);
503
504             Map<String, Type> genTOsMap = null;
505             if (parentModule != null && parentModule.getName() != null) {
506                 genTOsMap = genTypeDefsContextMap.get(parentModule.getName());
507             }
508
509             final GeneratedTOBuilder unionGenTransObject = typedefToTransferObject(
510                     basePackageName, typedef);
511             if ((unionTypes != null) && (unionGenTransObject != null)) {
512                 for (final TypeDefinition<?> unionType : unionTypes) {
513                     final String typeName = unionType.getQName()
514                             .getLocalName();
515                     if (unionType instanceof ExtendedType) {
516                         final Module unionTypeModule = findParentModuleForTypeDefinition(schemaContext,
517                                 unionType);
518                         if (unionTypeModule != null && unionTypeModule.getName() != null) {
519                             final Map<String, Type> innerGenTOs = genTypeDefsContextMap
520                                     .get(unionTypeModule.getName());
521
522                             final GeneratedTransferObject genTransferObject =
523                                     (GeneratedTransferObject) innerGenTOs.get(typeName);
524                             if (genTransferObject != null) {
525                                 updateUnionTypeAsProperty(unionGenTransObject,
526                                         genTransferObject,
527                                         genTransferObject.getName());
528                             }
529                         }
530                     } else if (unionType instanceof EnumTypeDefinition) {
531                         final EnumBuilder
532                                 enumBuilder = resolveInnerEnumFromTypeDefinition(
533                                 (EnumTypeDefinition) unionType, typeName,
534                                 unionGenTransObject);
535                         final Type enumRefType = new ReferencedTypeImpl(
536                                 enumBuilder.getPackageName(),
537                                 enumBuilder.getName());
538                         updateUnionTypeAsProperty(unionGenTransObject,
539                                 enumRefType, typeName);
540                     } else {
541                         final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
542                                 .javaTypeForSchemaDefinitionType(unionType);
543                         if (javaType != null) {
544                             updateUnionTypeAsProperty(unionGenTransObject,
545                                     javaType, typeName);
546                         }
547                     }
548                 }
549                 genTOsMap.put(typedef.getQName().getLocalName(),
550                         unionGenTransObject.toInstance());
551             }
552         }
553     }
554
555     private void updateUnionTypeAsProperty(
556             final GeneratedTOBuilder unionGenTransObject, final Type type,
557             final String propertyName) {
558         if (unionGenTransObject != null && type != null) {
559             final GeneratedPropertyBuilder propBuilder =
560                     unionGenTransObject.addProperty(parseToValidParamName(
561                             propertyName));
562             propBuilder.addReturnType(type);
563             propBuilder.setReadOnly(false);
564
565             if (!(type instanceof Enumeration)) {
566                 unionGenTransObject.addEqualsIdentity(propBuilder);
567                 unionGenTransObject.addHashIdentity(propBuilder);
568                 unionGenTransObject.addToStringProperty(propBuilder);
569             }
570         }
571     }
572
573     private GeneratedTOBuilder typedefToTransferObject(
574             final String basePackageName, final TypeDefinition<?> typedef) {
575
576         final String packageName = packageNameForGeneratedType(basePackageName,
577                 typedef.getPath());
578         final String typeDefTOName = typedef.getQName().getLocalName();
579
580         if ((packageName != null) && (typedef != null)
581                 && (typeDefTOName != null)) {
582             final String genTOName = parseToClassName(typeDefTOName);
583             final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(
584                     packageName, genTOName);
585
586             return newType;
587         }
588         return null;
589     }
590 }