ebefa1067e53530ef81be5431e574f05fe4944de
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-generator-impl / src / main / java / org / opendaylight / controller / sal / binding / generator / impl / BindingGeneratorImpl.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.generator.impl;
9
10 import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
11 import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode;
12 import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule;
13
14 import java.util.*;
15 import java.util.concurrent.Future;
16
17 import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
18 import org.opendaylight.controller.binding.generator.util.Types;
19 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
20 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
21 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
22 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
23 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
24 import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
25 import org.opendaylight.controller.sal.binding.model.api.Type;
26 import org.opendaylight.controller.sal.binding.model.api.type.builder.*;
27 import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
28 import org.opendaylight.controller.yang.binding.Notification;
29 import org.opendaylight.controller.yang.common.QName;
30 import org.opendaylight.controller.yang.common.RpcResult;
31 import org.opendaylight.controller.yang.model.api.*;
32 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
33 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
34 import org.opendaylight.controller.yang.model.util.DataNodeIterator;
35 import org.opendaylight.controller.yang.model.util.ExtendedType;
36 import org.opendaylight.controller.yang.model.util.SchemaContextUtil;
37
38 public final class BindingGeneratorImpl implements BindingGenerator {
39
40     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
41     private TypeProvider typeProvider;
42     private SchemaContext schemaContext;
43
44     public BindingGeneratorImpl() {
45         super();
46     }
47
48     @Override
49     public List<Type> generateTypes(final SchemaContext context) {
50         if (context == null) {
51             throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
52         }
53         if (context.getModules() == null) {
54             throw new IllegalStateException("Schema Context does not contain defined modules!");
55         }
56
57         final List<Type> generatedTypes = new ArrayList<>();
58         schemaContext = context;
59         typeProvider = new TypeProviderImpl(context);
60         final Set<Module> modules = context.getModules();
61         genTypeBuilders = new HashMap<>();
62         for (final Module module : modules) {
63             generatedTypes.add(moduleToDataType(module));
64             generatedTypes.addAll(allTypeDefinitionsToGenTypes(module));
65             generatedTypes.addAll(allContainersToGenTypes(module));
66             generatedTypes.addAll(allListsToGenTypes(module));
67             generatedTypes.addAll(allChoicesToGenTypes(module));
68             generatedTypes.addAll(allAugmentsToGenTypes(module));
69             generatedTypes.addAll(allRPCMethodsToGenType(module));
70             generatedTypes.addAll(allNotificationsToGenType(module));
71             generatedTypes.addAll(allIdentitiesToGenTypes(module, context));
72             generatedTypes.addAll(allGroupingsToGenTypes(module));
73         }
74         return generatedTypes;
75     }
76
77     @Override
78     public List<Type> generateTypes(final SchemaContext context, final Set<Module> modules) {
79         if (context == null) {
80             throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
81         }
82         if (context.getModules() == null) {
83             throw new IllegalStateException("Schema Context does not contain defined modules!");
84         }
85         if (modules == null) {
86             throw new IllegalArgumentException("Sef of Modules cannot be NULL!");
87         }
88
89         final List<Type> filteredGenTypes = new ArrayList<>();
90         schemaContext = context;
91         typeProvider = new TypeProviderImpl(context);
92         final Set<Module> contextModules = context.getModules();
93         genTypeBuilders = new HashMap<>();
94         for (final Module contextModule : contextModules) {
95             final List<Type> generatedTypes = new ArrayList<>();
96
97             generatedTypes.add(moduleToDataType(contextModule));
98             generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule));
99             generatedTypes.addAll(allContainersToGenTypes(contextModule));
100             generatedTypes.addAll(allListsToGenTypes(contextModule));
101             generatedTypes.addAll(allChoicesToGenTypes(contextModule));
102             generatedTypes.addAll(allAugmentsToGenTypes(contextModule));
103             generatedTypes.addAll(allRPCMethodsToGenType(contextModule));
104             generatedTypes.addAll(allNotificationsToGenType(contextModule));
105             generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context));
106             generatedTypes.addAll(allGroupingsToGenTypes(contextModule));
107
108             if (modules.contains(contextModule)) {
109                 filteredGenTypes.addAll(generatedTypes);
110             }
111         }
112         return filteredGenTypes;
113     }
114
115     private List<Type> allTypeDefinitionsToGenTypes(final Module module) {
116         if (module == null) {
117             throw new IllegalArgumentException("Module reference cannot be NULL!");
118         }
119         if (module.getName() == null) {
120             throw new IllegalArgumentException("Module name cannot be NULL!");
121         }
122         if (module.getTypeDefinitions() == null) {
123             throw new IllegalArgumentException("Type Definitions for module " + module.getName() + " cannot be NULL!");
124         }
125
126         final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
127         final List<Type> generatedTypes = new ArrayList<>();
128         for (final TypeDefinition<?> typedef : typeDefinitions) {
129             if (typedef != null) {
130                 final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef);
131                 if ((type != null) && !generatedTypes.contains(type)) {
132                     generatedTypes.add(type);
133                 }
134             }
135         }
136         return generatedTypes;
137     }
138
139     private List<Type> allContainersToGenTypes(final Module module) {
140         if (module == null) {
141             throw new IllegalArgumentException("Module reference cannot be NULL!");
142         }
143
144         if (module.getName() == null) {
145             throw new IllegalArgumentException("Module name cannot be NULL!");
146         }
147
148         if (module.getChildNodes() == null) {
149             throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()
150                     + " cannot be NULL!");
151         }
152
153         final List<Type> generatedTypes = new ArrayList<>();
154         final DataNodeIterator it = new DataNodeIterator(module);
155         final List<ContainerSchemaNode> schemaContainers = it.allContainers();
156         final String basePackageName = moduleNamespaceToPackageName(module);
157         for (final ContainerSchemaNode container : schemaContainers) {
158             generatedTypes.add(containerToGenType(basePackageName, container));
159         }
160         return generatedTypes;
161     }
162
163     private List<Type> allListsToGenTypes(final Module module) {
164         if (module == null) {
165             throw new IllegalArgumentException("Module reference cannot be NULL!");
166         }
167
168         if (module.getName() == null) {
169             throw new IllegalArgumentException("Module name cannot be NULL!");
170         }
171
172         if (module.getChildNodes() == null) {
173             throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()
174                     + " cannot be NULL!");
175         }
176
177         final List<Type> generatedTypes = new ArrayList<>();
178         final DataNodeIterator it = new DataNodeIterator(module);
179         final List<ListSchemaNode> schemaLists = it.allLists();
180         final String basePackageName = moduleNamespaceToPackageName(module);
181         if (schemaLists != null) {
182             for (final ListSchemaNode list : schemaLists) {
183                 generatedTypes.addAll(listToGenType(basePackageName, list));
184             }
185         }
186         return generatedTypes;
187     }
188
189     private List<GeneratedType> allChoicesToGenTypes(final Module module) {
190         if (module == null) {
191             throw new IllegalArgumentException("Module reference cannot be NULL!");
192         }
193         if (module.getName() == null) {
194             throw new IllegalArgumentException("Module name cannot be NULL!");
195         }
196
197         final DataNodeIterator it = new DataNodeIterator(module);
198         final List<ChoiceNode> choiceNodes = it.allChoices();
199         final String basePackageName = moduleNamespaceToPackageName(module);
200
201         final List<GeneratedType> generatedTypes = new ArrayList<>();
202         for (final ChoiceNode choice : choiceNodes) {
203             if (choice != null) {
204                 generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice));
205             }
206         }
207         return generatedTypes;
208     }
209
210     private List<Type> allAugmentsToGenTypes(final Module module) {
211         if (module == null) {
212             throw new IllegalArgumentException("Module reference cannot be NULL!");
213         }
214         if (module.getName() == null) {
215             throw new IllegalArgumentException("Module name cannot be NULL!");
216         }
217         if (module.getChildNodes() == null) {
218             throw new IllegalArgumentException("Reference to Set of Augmentation Definitions in module "
219                     + module.getName() + " cannot be NULL!");
220         }
221
222         final List<Type> generatedTypes = new ArrayList<>();
223         final String basePackageName = moduleNamespaceToPackageName(module);
224         final List<AugmentationSchema> augmentations = resolveAugmentations(module);
225         for (final AugmentationSchema augment : augmentations) {
226             generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment));
227         }
228         return generatedTypes;
229     }
230
231     private List<AugmentationSchema> resolveAugmentations(final Module module) {
232         if (module == null) {
233             throw new IllegalArgumentException("Module reference cannot be NULL!");
234         }
235         if (module.getAugmentations() == null) {
236             throw new IllegalStateException("Augmentations Set cannot be NULL!");
237         }
238
239         final Set<AugmentationSchema> augmentations = module.getAugmentations();
240         final List<AugmentationSchema> sortedAugmentations = new ArrayList<>(augmentations);
241         Collections.sort(sortedAugmentations, new Comparator<AugmentationSchema>() {
242
243             @Override
244             public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) {
245
246                 if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) {
247                     return 1;
248                 } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) {
249                     return -1;
250                 }
251                 return 0;
252
253             }
254         });
255
256         return sortedAugmentations;
257     }
258
259     private GeneratedType moduleToDataType(final Module module) {
260         if (module == null) {
261             throw new IllegalArgumentException("Module reference cannot be NULL!");
262         }
263
264         final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");
265
266         final String basePackageName = moduleNamespaceToPackageName(module);
267         if (moduleDataTypeBuilder != null) {
268             final Set<DataSchemaNode> dataNodes = module.getChildNodes();
269             resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes);
270         }
271         return moduleDataTypeBuilder.toInstance();
272     }
273
274     private List<Type> allRPCMethodsToGenType(final Module module) {
275         if (module == null) {
276             throw new IllegalArgumentException("Module reference cannot be NULL!");
277         }
278
279         if (module.getName() == null) {
280             throw new IllegalArgumentException("Module name cannot be NULL!");
281         }
282
283         if (module.getChildNodes() == null) {
284             throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module "
285                     + module.getName() + " cannot be NULL!");
286         }
287
288         final String basePackageName = moduleNamespaceToPackageName(module);
289         final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
290         final List<Type> genRPCTypes = new ArrayList<>();
291         final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service");
292         final Type future = Types.typeForClass(Future.class);
293         for (final RpcDefinition rpc : rpcDefinitions) {
294             if (rpc != null) {
295
296                 String rpcName = parseToClassName(rpc.getQName().getLocalName());
297                 MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcName);
298
299                 final List<DataNodeIterator> rpcInOut = new ArrayList<>();
300
301                 ContainerSchemaNode input = rpc.getInput();
302                 ContainerSchemaNode output = rpc.getOutput();
303
304                 if (input != null) {
305                     rpcInOut.add(new DataNodeIterator(input));
306                     GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName);
307                     resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes());
308                     Type inTypeInstance = inType.toInstance();
309                     genRPCTypes.add(inTypeInstance);
310                     method.addParameter(inTypeInstance, "input");
311                 }
312
313                 Type outTypeInstance = Types.typeForClass(Void.class);
314                 if (output != null) {
315                     rpcInOut.add(new DataNodeIterator(output));
316
317                     GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName);
318                     resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes());
319                     outTypeInstance = outType.toInstance();
320                     genRPCTypes.add(outTypeInstance);
321
322                 }
323
324                 final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance);
325                 method.setReturnType(Types.parameterizedTypeFor(future, rpcRes));
326                 for (DataNodeIterator it : rpcInOut) {
327                     List<ContainerSchemaNode> nContainers = it.allContainers();
328                     if ((nContainers != null) && !nContainers.isEmpty()) {
329                         for (final ContainerSchemaNode container : nContainers) {
330                             genRPCTypes.add(containerToGenType(basePackageName, container));
331                         }
332                     }
333                     List<ListSchemaNode> nLists = it.allLists();
334                     if ((nLists != null) && !nLists.isEmpty()) {
335                         for (final ListSchemaNode list : nLists) {
336                             genRPCTypes.addAll(listToGenType(basePackageName, list));
337                         }
338                     }
339                 }
340             }
341         }
342         genRPCTypes.add(interfaceBuilder.toInstance());
343         return genRPCTypes;
344     }
345
346     private List<Type> allNotificationsToGenType(final Module module) {
347         if (module == null) {
348             throw new IllegalArgumentException("Module reference cannot be NULL!");
349         }
350
351         if (module.getName() == null) {
352             throw new IllegalArgumentException("Module name cannot be NULL!");
353         }
354
355         if (module.getChildNodes() == null) {
356             throw new IllegalArgumentException("Reference to Set of Notification Definitions in module "
357                     + module.getName() + " cannot be NULL!");
358         }
359
360         final String basePackageName = moduleNamespaceToPackageName(module);
361         final List<Type> genNotifyTypes = new ArrayList<>();
362         final Set<NotificationDefinition> notifications = module.getNotifications();
363
364         for (final NotificationDefinition notification : notifications) {
365             if (notification != null) {
366                 DataNodeIterator it = new DataNodeIterator(notification);
367
368                 // Containers
369                 for (ContainerSchemaNode node : it.allContainers()) {
370                     genNotifyTypes.add(containerToGenType(basePackageName, node));
371                 }
372                 // Lists
373                 for (ListSchemaNode node : it.allLists()) {
374                     genNotifyTypes.addAll(listToGenType(basePackageName, node));
375                 }
376                 final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName,
377                         notification);
378                 notificationTypeBuilder.addImplementsType(Types.typeForClass(Notification.class));
379                 // Notification object
380                 resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes());
381                 genNotifyTypes.add(notificationTypeBuilder.toInstance());
382             }
383         }
384         return genNotifyTypes;
385     }
386
387     private List<Type> allIdentitiesToGenTypes(final Module module, final SchemaContext context) {
388         List<Type> genTypes = new ArrayList<>();
389
390         final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
391
392         final String basePackageName = moduleNamespaceToPackageName(module);
393
394         if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
395             for (final IdentitySchemaNode identity : schemaIdentities) {
396                 genTypes.add(identityToGenType(basePackageName, identity, context));
397             }
398         }
399         return genTypes;
400     }
401
402     private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity,
403             final SchemaContext context) {
404         if (identity == null) {
405             return null;
406         }
407
408         final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
409         final String genTypeName = parseToClassName(identity.getQName().getLocalName());
410         final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName);
411
412         IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
413         if (baseIdentity != null) {
414             Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);
415
416             final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
417             final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName());
418
419             GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();
420             newType.setExtendsType(gto);
421         } else {
422             newType.setExtendsType(Types.getBaseIdentityTO());
423         }
424         newType.setAbstract(true);
425         return newType.toInstance();
426     }
427
428     private List<Type> allGroupingsToGenTypes(final Module module) {
429         final List<Type> genTypes = new ArrayList<>();
430         final String basePackageName = moduleNamespaceToPackageName(module);
431         final Set<GroupingDefinition> groupings = module.getGroupings();
432         if (groupings != null && !groupings.isEmpty()) {
433             for (final GroupingDefinition grouping : groupings) {
434                 genTypes.add(groupingToGenType(basePackageName, grouping));
435             }
436         }
437         return genTypes;
438     }
439
440     private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) {
441         if (grouping == null) {
442             return null;
443         }
444
445         final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath());
446         final Set<DataSchemaNode> schemaNodes = grouping.getChildNodes();
447         final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping);
448
449         resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
450         return typeBuilder.toInstance();
451     }
452
453     private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition<?> typeDefinition) {
454         if (typeDefinition != null) {
455             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
456                 return (EnumTypeDefinition) typeDefinition.getBaseType();
457             } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
458                 return enumTypeDefFromExtendedType(typeDefinition.getBaseType());
459             }
460         }
461         return null;
462     }
463
464     private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName,
465             final GeneratedTypeBuilder typeBuilder) {
466         if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null)
467                 && (enumTypeDef.getQName().getLocalName() != null)) {
468
469             final String enumerationName = parseToClassName(enumName);
470             final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
471
472             if (enumBuilder != null) {
473                 final List<EnumPair> enums = enumTypeDef.getValues();
474                 if (enums != null) {
475                     int listIndex = 0;
476                     for (final EnumPair enumPair : enums) {
477                         if (enumPair != null) {
478                             final String enumPairName = parseToClassName(enumPair.getName());
479                             Integer enumPairValue = enumPair.getValue();
480
481                             if (enumPairValue == null) {
482                                 enumPairValue = listIndex;
483                             }
484                             enumBuilder.addValue(enumPairName, enumPairValue);
485                             listIndex++;
486                         }
487                     }
488                 }
489                 return enumBuilder;
490             }
491         }
492         return null;
493     }
494
495     private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) {
496         if (module == null) {
497             throw new IllegalArgumentException("Module reference cannot be NULL!");
498         }
499         String packageName = moduleNamespaceToPackageName(module);
500         final String moduleName = parseToClassName(module.getName()) + postfix;
501
502         return new GeneratedTypeBuilderImpl(packageName, moduleName);
503
504     }
505
506     private List<Type> augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) {
507         if (augmentPackageName == null) {
508             throw new IllegalArgumentException("Package Name cannot be NULL!");
509         }
510         if (augSchema == null) {
511             throw new IllegalArgumentException("Augmentation Schema cannot be NULL!");
512         }
513         if (augSchema.getTargetPath() == null) {
514             throw new IllegalStateException("Augmentation Schema does not contain Target Path (Target Path is NULL).");
515         }
516
517         final List<Type> genTypes = new ArrayList<>();
518
519         // EVERY augmented interface will extends Augmentation<T> interface
520         // and DataObject interface!!!
521         final SchemaPath targetPath = augSchema.getTargetPath();
522         final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
523         if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null)
524                 && (targetSchemaNode.getQName().getLocalName() != null)) {
525             final Module targetModule = findParentModule(schemaContext, targetSchemaNode);
526             final String targetBasePackage = moduleNamespaceToPackageName(targetModule);
527             final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath());
528             final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName();
529             final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
530
531             if (!(targetSchemaNode instanceof ChoiceNode)) {
532                 final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,
533                         targetPackageName, targetSchemaNodeName, augSchema);
534                 final GeneratedType augType = augTypeBuilder.toInstance();
535                 genTypes.add(augType);
536             } else {
537                 final Type refChoiceType = new ReferencedTypeImpl(targetPackageName,
538                         parseToClassName(targetSchemaNodeName));
539                 final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode;
540                 final Set<ChoiceCaseNode> choiceCaseNodes = choiceTarget.getCases();
541                 genTypes.addAll(augmentCasesToGenTypes(augmentPackageName, refChoiceType, choiceCaseNodes));
542             }
543             genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes));
544         }
545         return genTypes;
546     }
547
548     private List<GeneratedType> augmentCasesToGenTypes(final String augmentPackageName, final Type refChoiceType,
549             final Set<ChoiceCaseNode> choiceCaseNodes) {
550         if (augmentPackageName == null) {
551             throw new IllegalArgumentException("Augment Package Name string cannot be NULL!");
552         }
553         if (choiceCaseNodes == null) {
554             throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
555         }
556         final List<GeneratedType> genTypes = generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType,
557                 choiceCaseNodes);
558         return genTypes;
559     }
560
561     private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName,
562             final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) {
563         final String targetTypeName = parseToClassName(targetSchemaNodeName);
564         Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
565         if (augmentBuilders == null) {
566             augmentBuilders = new HashMap<>();
567             genTypeBuilders.put(augmentPackageName, augmentBuilders);
568         }
569
570         final String augTypeName = augGenTypeName(augmentBuilders, targetTypeName);
571         final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName);
572         final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
573
574         final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);
575
576         augTypeBuilder.addImplementsType(Types.DATA_OBJECT);
577         augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));
578
579         augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes);
580         augmentBuilders.put(augTypeName, augTypeBuilder);
581         return augTypeBuilder;
582     }
583
584     private List<Type> augmentationBodyToGenTypes(final String augBasePackageName,
585             final Set<DataSchemaNode> augChildNodes) {
586         final List<Type> genTypes = new ArrayList<>();
587         final List<DataNodeIterator> augSchemaIts = new ArrayList<>();
588         for (final DataSchemaNode childNode : augChildNodes) {
589             if (childNode instanceof DataNodeContainer) {
590                 augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode));
591
592                 if (childNode instanceof ContainerSchemaNode) {
593                     genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode));
594                 } else if (childNode instanceof ListSchemaNode) {
595                     genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode));
596                 }
597             } else if (childNode instanceof ChoiceNode) {
598                 final ChoiceNode choice = (ChoiceNode) childNode;
599                 for (final ChoiceCaseNode caseNode : choice.getCases()) {
600                     augSchemaIts.add(new DataNodeIterator(caseNode));
601                 }
602                 genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode));
603             }
604         }
605
606         for (final DataNodeIterator it : augSchemaIts) {
607             final List<ContainerSchemaNode> augContainers = it.allContainers();
608             final List<ListSchemaNode> augLists = it.allLists();
609             final List<ChoiceNode> augChoices = it.allChoices();
610
611             if (augContainers != null) {
612                 for (final ContainerSchemaNode container : augContainers) {
613                     genTypes.add(containerToGenType(augBasePackageName, container));
614                 }
615             }
616             if (augLists != null) {
617                 for (final ListSchemaNode list : augLists) {
618                     genTypes.addAll(listToGenType(augBasePackageName, list));
619                 }
620             }
621             if (augChoices != null) {
622                 for (final ChoiceNode choice : augChoices) {
623                     genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice));
624                 }
625             }
626         }
627         return genTypes;
628     }
629
630     private String augGenTypeName(final Map<String, GeneratedTypeBuilder> builders, final String genTypeName) {
631         String augTypeName = genTypeName;
632
633         int index = 1;
634         while ((builders != null) && builders.containsKey(genTypeName + index)) {
635             index++;
636         }
637         augTypeName += index;
638         return augTypeName;
639     }
640
641     private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) {
642         if (containerNode == null) {
643             return null;
644         }
645
646         final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
647         final Set<DataSchemaNode> schemaNodes = containerNode.getChildNodes();
648         final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode);
649
650         resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
651         return typeBuilder.toInstance();
652     }
653
654     private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName,
655             final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
656         if ((schemaNodes != null) && (typeBuilder != null)) {
657             for (final DataSchemaNode schemaNode : schemaNodes) {
658                 if (schemaNode.isAugmenting()) {
659                     continue;
660                 }
661                 addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
662             }
663         }
664         return typeBuilder;
665     }
666
667     private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName,
668             final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
669         if ((schemaNodes != null) && (typeBuilder != null)) {
670             for (final DataSchemaNode schemaNode : schemaNodes) {
671                 if (schemaNode.isAugmenting()) {
672                     addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
673                 }
674             }
675         }
676         return typeBuilder;
677     }
678
679     private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode,
680             final GeneratedTypeBuilder typeBuilder) {
681         if (schemaNode != null && typeBuilder != null) {
682             if (schemaNode instanceof LeafSchemaNode) {
683                 resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode);
684             } else if (schemaNode instanceof LeafListSchemaNode) {
685                 resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
686             } else if (schemaNode instanceof ContainerSchemaNode) {
687                 resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);
688             } else if (schemaNode instanceof ListSchemaNode) {
689                 resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);
690             } else if (schemaNode instanceof ChoiceNode) {
691                 resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode);
692             }
693         }
694     }
695
696     private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
697             final ChoiceNode choiceNode) {
698         if (basePackageName == null) {
699             throw new IllegalArgumentException("Base Package Name cannot be NULL!");
700         }
701         if (typeBuilder == null) {
702             throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
703         }
704         if (choiceNode == null) {
705             throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");
706         }
707
708         final String choiceName = choiceNode.getQName().getLocalName();
709         if (choiceName != null) {
710             final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
711             final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode);
712             constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType);
713         }
714     }
715
716     private List<GeneratedType> choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) {
717         if (basePackageName == null) {
718             throw new IllegalArgumentException("Base Package Name cannot be NULL!");
719         }
720         if (choiceNode == null) {
721             throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");
722         }
723
724         final List<GeneratedType> generatedTypes = new ArrayList<>();
725         final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
726         final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
727         choiceTypeBuilder.addImplementsType(Types.DATA_OBJECT);
728         final GeneratedType choiceType = choiceTypeBuilder.toInstance();
729
730         generatedTypes.add(choiceType);
731         final Set<ChoiceCaseNode> caseNodes = choiceNode.getCases();
732         if ((caseNodes != null) && !caseNodes.isEmpty()) {
733             generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes));
734         }
735         return generatedTypes;
736     }
737
738     private List<GeneratedType> generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType,
739             final Set<ChoiceCaseNode> caseNodes) {
740         if (basePackageName == null) {
741             throw new IllegalArgumentException("Base Package Name cannot be NULL!");
742         }
743         if (refChoiceType == null) {
744             throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
745         }
746         if (caseNodes == null) {
747             throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
748         }
749
750         final List<GeneratedType> generatedTypes = new ArrayList<>();
751         for (final ChoiceCaseNode caseNode : caseNodes) {
752             if (caseNode != null && !caseNode.isAddedByUses()) {
753                 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
754                 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
755                 caseTypeBuilder.addImplementsType(refChoiceType);
756
757                 final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
758                 if (childNodes != null) {
759                     resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
760                 }
761                 generatedTypes.add(caseTypeBuilder.toInstance());
762             }
763         }
764
765         return generatedTypes;
766     }
767
768     private List<GeneratedType> generateTypesFromAugmentedChoiceCases(final String basePackageName,
769             final Type refChoiceType, final Set<ChoiceCaseNode> caseNodes) {
770         if (basePackageName == null) {
771             throw new IllegalArgumentException("Base Package Name cannot be NULL!");
772         }
773         if (refChoiceType == null) {
774             throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
775         }
776         if (caseNodes == null) {
777             throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
778         }
779
780         final List<GeneratedType> generatedTypes = new ArrayList<>();
781         for (final ChoiceCaseNode caseNode : caseNodes) {
782             if (caseNode != null && caseNode.isAugmenting()) {
783                 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
784                 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
785                 caseTypeBuilder.addImplementsType(refChoiceType);
786
787                 final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
788                 if (childNodes != null) {
789                     resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
790                 }
791                 generatedTypes.add(caseTypeBuilder.toInstance());
792             }
793         }
794
795         return generatedTypes;
796     }
797
798     private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
799         if ((leaf != null) && (typeBuilder != null)) {
800             final String leafName = leaf.getQName().getLocalName();
801             String leafDesc = leaf.getDescription();
802             if (leafDesc == null) {
803                 leafDesc = "";
804             }
805
806             if (leafName != null) {
807                 final TypeDefinition<?> typeDef = leaf.getType();
808
809                 Type returnType = null;
810                 if (!(typeDef instanceof EnumTypeDefinition)) {
811                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
812                 } else {
813                     final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
814                     final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName,
815                             typeBuilder);
816
817                     if (enumBuilder != null) {
818                         returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
819                     }
820                     ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
821                 }
822                 if (returnType != null) {
823                     constructGetter(typeBuilder, leafName, leafDesc, returnType);
824                     if (!leaf.isConfiguration()) {
825                         constructSetter(typeBuilder, leafName, leafDesc, returnType);
826                     }
827                     return true;
828                 }
829             }
830         }
831         return false;
832     }
833
834     private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
835             boolean isReadOnly) {
836         if ((leaf != null) && (toBuilder != null)) {
837             final String leafName = leaf.getQName().getLocalName();
838             String leafDesc = leaf.getDescription();
839             if (leafDesc == null) {
840                 leafDesc = "";
841             }
842
843             if (leafName != null) {
844                 final TypeDefinition<?> typeDef = leaf.getType();
845
846                 // TODO: properly resolve enum types
847                 final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
848
849                 if (returnType != null) {
850                     final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName));
851
852                     propBuilder.setReadOnly(isReadOnly);
853                     propBuilder.setReturnType(returnType);
854                     propBuilder.setComment(leafDesc);
855
856                     toBuilder.addEqualsIdentity(propBuilder);
857                     toBuilder.addHashIdentity(propBuilder);
858                     toBuilder.addToStringProperty(propBuilder);
859
860                     return true;
861                 }
862             }
863         }
864         return false;
865     }
866
867     private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) {
868         if ((node != null) && (typeBuilder != null)) {
869             final String nodeName = node.getQName().getLocalName();
870             String nodeDesc = node.getDescription();
871             if (nodeDesc == null) {
872                 nodeDesc = "";
873             }
874
875             if (nodeName != null) {
876                 final TypeDefinition<?> type = node.getType();
877                 final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type));
878
879                 constructGetter(typeBuilder, nodeName, nodeDesc, listType);
880                 if (!node.isConfiguration()) {
881                     constructSetter(typeBuilder, nodeName, nodeDesc, listType);
882                 }
883                 return true;
884             }
885         }
886         return false;
887     }
888
889     private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
890             final ContainerSchemaNode containerNode) {
891         if ((containerNode != null) && (typeBuilder != null)) {
892             final String nodeName = containerNode.getQName().getLocalName();
893
894             if (nodeName != null) {
895                 final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
896
897                 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode);
898                 constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType);
899
900                 return true;
901             }
902         }
903         return false;
904     }
905
906     private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
907             final ListSchemaNode schemaNode) {
908         if ((schemaNode != null) && (typeBuilder != null)) {
909             final String listName = schemaNode.getQName().getLocalName();
910
911             if (listName != null) {
912                 final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath());
913                 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode);
914                 constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
915                 if (!schemaNode.isConfiguration()) {
916                     constructSetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
917                 }
918                 return true;
919             }
920         }
921         return false;
922     }
923
924     /**
925      * Method instantiates new Generated Type Builder and sets the implements
926      * definitions of Data Object and Augmentable.
927      * 
928      * @param packageName
929      *            Generated Type Package Name
930      * @param schemaNode
931      *            Schema Node definition
932      * @return Generated Type Builder instance for Schema Node definition
933      */
934     private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
935         final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, "");
936         builder.addImplementsType(Types.DATA_OBJECT);
937         builder.addImplementsType(Types.augmentableTypeFor(builder));
938         return builder;
939     }
940
941     /**
942      * 
943      * @param packageName
944      * @param schemaNode
945      * @return
946      */
947     private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
948         return addRawInterfaceDefinition(packageName, schemaNode, "");
949     }
950
951     private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode,
952             final String prefix) {
953         if (schemaNode == null) {
954             throw new IllegalArgumentException("Data Schema Node cannot be NULL!");
955         }
956         if (packageName == null) {
957             throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
958         }
959         if (schemaNode.getQName() == null) {
960             throw new IllegalArgumentException("QName for Data Schema Node cannot be NULL!");
961         }
962         final String schemaNodeName = schemaNode.getQName().getLocalName();
963         if (schemaNodeName == null) {
964             throw new IllegalArgumentException("Local Name of QName for Data Schema Node cannot be NULL!");
965         }
966
967         final String genTypeName;
968         if (prefix == null) {
969             genTypeName = parseToClassName(schemaNodeName);
970         } else {
971             genTypeName = prefix + parseToClassName(schemaNodeName);
972         }
973
974         final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
975         if (!genTypeBuilders.containsKey(packageName)) {
976             final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();
977             builders.put(genTypeName, newType);
978             genTypeBuilders.put(packageName, builders);
979         } else {
980             final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
981             if (!builders.containsKey(genTypeName)) {
982                 builders.put(genTypeName, newType);
983             }
984         }
985         return newType;
986     }
987
988     private String getterMethodName(final String methodName) {
989         final StringBuilder method = new StringBuilder();
990         method.append("get");
991         method.append(parseToClassName(methodName));
992         return method.toString();
993     }
994
995     private String setterMethodName(final String methodName) {
996         final StringBuilder method = new StringBuilder();
997         method.append("set");
998         method.append(parseToClassName(methodName));
999         return method.toString();
1000     }
1001
1002     private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder,
1003             final String schemaNodeName, final String comment, final Type returnType) {
1004         final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName));
1005
1006         getMethod.setComment(comment);
1007         getMethod.setReturnType(returnType);
1008
1009         return getMethod;
1010     }
1011
1012     private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder,
1013             final String schemaNodeName, final String comment, final Type parameterType) {
1014         final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName));
1015
1016         setMethod.setComment(comment);
1017         setMethod.addParameter(parameterType, parseToValidParamName(schemaNodeName));
1018         setMethod.setReturnType(Types.voidType());
1019
1020         return setMethod;
1021     }
1022
1023     private List<Type> listToGenType(final String basePackageName, final ListSchemaNode list) {
1024         if (basePackageName == null) {
1025             throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
1026         }
1027         if (list == null) {
1028             throw new IllegalArgumentException("List Schema Node cannot be NULL!");
1029         }
1030
1031         final String packageName = packageNameForGeneratedType(basePackageName, list.getPath());
1032         final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(packageName, list);
1033         final List<String> listKeys = listKeys(list);
1034         GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list, listKeys);
1035
1036         final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
1037
1038         for (final DataSchemaNode schemaNode : schemaNodes) {
1039             if (schemaNode.isAugmenting()) {
1040                 continue;
1041             }
1042             addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys);
1043         }
1044         return typeBuildersToGenTypes(typeBuilder, genTOBuilder);
1045     }
1046
1047     private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode,
1048             final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List<String> listKeys) {
1049         if (schemaNode == null) {
1050             throw new IllegalArgumentException("Data Schema Node cannot be NULL!");
1051         }
1052
1053         if (typeBuilder == null) {
1054             throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
1055         }
1056
1057         if (schemaNode instanceof LeafSchemaNode) {
1058             final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
1059             if (!isPartOfListKey(leaf, listKeys)) {
1060                 resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
1061             } else {
1062                 resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
1063             }
1064         } else if (schemaNode instanceof LeafListSchemaNode) {
1065             resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
1066         } else if (schemaNode instanceof ContainerSchemaNode) {
1067             resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);
1068         } else if (schemaNode instanceof ListSchemaNode) {
1069             resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);
1070         }
1071     }
1072
1073     private List<Type> typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) {
1074         final List<Type> genTypes = new ArrayList<>();
1075         if (typeBuilder == null) {
1076             throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
1077         }
1078
1079         if (genTOBuilder != null) {
1080             final GeneratedTransferObject genTO = genTOBuilder.toInstance();
1081             constructGetter(typeBuilder, genTO.getName(), "Returns Primary Key of Yang List Type", genTO);
1082             genTypes.add(genTO);
1083         }
1084         genTypes.add(typeBuilder.toInstance());
1085         return genTypes;
1086     }
1087
1088     /**
1089      * @param list
1090      * @return
1091      */
1092     private GeneratedTOBuilder resolveListKey(final String packageName, final ListSchemaNode list) {
1093         final String listName = list.getQName().getLocalName() + "Key";
1094         return schemaNodeToTransferObjectBuilder(packageName, list, listName);
1095     }
1096
1097     private boolean isPartOfListKey(final LeafSchemaNode leaf, final List<String> keys) {
1098         if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
1099             final String leafName = leaf.getQName().getLocalName();
1100             if (keys.contains(leafName)) {
1101                 return true;
1102             }
1103         }
1104         return false;
1105     }
1106
1107     private List<String> listKeys(final ListSchemaNode list) {
1108         final List<String> listKeys = new ArrayList<>();
1109
1110         if (list.getKeyDefinition() != null) {
1111             final List<QName> keyDefinitions = list.getKeyDefinition();
1112
1113             for (final QName keyDefinition : keyDefinitions) {
1114                 listKeys.add(keyDefinition.getLocalName());
1115             }
1116         }
1117         return listKeys;
1118     }
1119
1120     private GeneratedTypeBuilder resolveListTypeBuilder(final String packageName, final ListSchemaNode list) {
1121         if (packageName == null) {
1122             throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
1123         }
1124         if (list == null) {
1125             throw new IllegalArgumentException("List Schema Node cannot be NULL!");
1126         }
1127
1128         final String schemaNodeName = list.getQName().getLocalName();
1129         final String genTypeName = parseToClassName(schemaNodeName);
1130
1131         GeneratedTypeBuilder typeBuilder = null;
1132         final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
1133         if (builders != null) {
1134             typeBuilder = builders.get(genTypeName);
1135         }
1136         if (typeBuilder == null) {
1137             typeBuilder = addDefaultInterfaceDefinition(packageName, list);
1138         }
1139         return typeBuilder;
1140     }
1141
1142     private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list,
1143             final List<String> listKeys) {
1144         GeneratedTOBuilder genTOBuilder = null;
1145         if (listKeys.size() > 0) {
1146             genTOBuilder = resolveListKey(packageName, list);
1147         }
1148         return genTOBuilder;
1149     }
1150 }