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