Added capability to resolve Enumeration type definitions;
[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 java.net.URI;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Calendar;
14 import java.util.GregorianCalendar;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20
21 import org.opendaylight.controller.binding.generator.util.CodeGeneratorHelper;
22 import org.opendaylight.controller.binding.generator.util.Types;
23 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
24 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
25 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
26 import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
27 import org.opendaylight.controller.sal.binding.model.api.Type;
28 import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;
29 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
30 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
31 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
32 import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder;
33 import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
34 import org.opendaylight.controller.yang.common.QName;
35 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
36 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
37 import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
38 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
39 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
40 import org.opendaylight.controller.yang.model.api.Module;
41 import org.opendaylight.controller.yang.model.api.NotificationDefinition;
42 import org.opendaylight.controller.yang.model.api.RpcDefinition;
43 import org.opendaylight.controller.yang.model.api.SchemaContext;
44 import org.opendaylight.controller.yang.model.api.SchemaPath;
45 import org.opendaylight.controller.yang.model.api.TypeDefinition;
46 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
47 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
48 import org.opendaylight.controller.yang.model.util.DataNodeIterator;
49 import org.opendaylight.controller.yang.model.util.ExtendedType;
50
51 public class BindingGeneratorImpl implements BindingGenerator {
52
53     private static final String[] SET_VALUES = new String[] { "abstract",
54             "assert", "boolean", "break", "byte", "case", "catch", "char",
55             "class", "const", "continue", "default", "double", "do", "else",
56             "enum", "extends", "false", "final", "finally", "float", "for",
57             "goto", "if", "implements", "import", "instanceof", "int",
58             "interface", "long", "native", "new", "null", "package", "private",
59             "protected", "public", "return", "short", "static", "strictfp",
60             "super", "switch", "synchronized", "this", "throw", "throws",
61             "transient", "true", "try", "void", "volatile", "while" };
62
63     public static final Set<String> JAVA_RESERVED_WORDS = new HashSet<String>(
64             Arrays.asList(SET_VALUES));
65
66     private static Calendar calendar = new GregorianCalendar();
67     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
68     private TypeProvider typeProvider;
69     private String basePackageName;
70
71     public BindingGeneratorImpl() {
72         super();
73     }
74
75     private static String validatePackage(final String packageName) {
76         if (packageName != null) {
77             final String[] packNameParts = packageName.split("\\.");
78             if (packNameParts != null) {
79                 final StringBuilder builder = new StringBuilder();
80                 for (int i = 0; i < packNameParts.length; ++i) {
81                     if (JAVA_RESERVED_WORDS.contains(packNameParts[i])) {
82                         packNameParts[i] = "_" + packNameParts[i];
83                     }
84                     if (i > 0) {
85                         builder.append(".");
86                     }
87                     builder.append(packNameParts[i]);
88                 }
89                 return builder.toString();
90             }
91         }
92         return packageName;
93     }
94
95     @Override
96     public List<Type> generateTypes(final SchemaContext context) {
97         final List<Type> genTypes = new ArrayList<Type>();
98
99         typeProvider = new TypeProviderImpl(context);
100         if (context != null) {
101             final Set<Module> modules = context.getModules();
102
103             if (modules != null) {
104                 for (final Module module : modules) {
105                     DataNodeIterator moduleIterator = new DataNodeIterator(module);
106                     
107                     genTypeBuilders = new HashMap<String, Map<String, GeneratedTypeBuilder>>();
108                     final List<ContainerSchemaNode> schemaContainers = moduleIterator.allContainers();
109                     final List<ListSchemaNode> schemaLists = moduleIterator.allLists();
110
111                     basePackageName = resolveBasePackageName(
112                             module.getNamespace(), module.getYangVersion());
113
114                     if (schemaContainers.size() > 0) {
115                         for (final ContainerSchemaNode container : schemaContainers) {
116                             genTypes.add(containerToGenType(container));
117                         }
118                     }
119                     if (schemaLists.size() > 0) {
120                         for (final ListSchemaNode list : schemaLists) {
121                             genTypes.addAll(listToGenType(list));
122                         }
123                     }
124
125                     final GeneratedType genDataType = moduleToDataType(module);
126                     final GeneratedType genRpcType = rpcMethodsToGenType(module);
127                     final GeneratedType genNotifyType = notifycationsToGenType(module);
128
129                     if (genDataType != null) {
130                         genTypes.add(genDataType);
131                     }
132                     if (genRpcType != null) {
133                         genTypes.add(genRpcType);
134                     }
135                     if (genNotifyType != null) {
136                         genTypes.add(genNotifyType);
137                     }
138                 }
139             }
140         }
141         return genTypes;
142     }
143
144     private GeneratedType moduleToDataType(final Module module) {
145         if (module != null) {
146             final Set<TypeDefinition<?>> typeDefinitions = module
147                     .getTypeDefinitions();
148             final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(
149                     module, "Data");
150
151             if (moduleDataTypeBuilder != null) {
152                 if (typeDefinitions != null) {
153                     for (final TypeDefinition<?> typedef : typeDefinitions) {
154                         if (isDerivedFromEnumerationType(typedef)) {
155                             final EnumTypeDefinition enumBaseType = enumTypeDefFromExtendedType(typedef);
156                             resolveEnumFromTypeDefinition(enumBaseType, typedef
157                                     .getQName().getLocalName(),
158                                     moduleDataTypeBuilder);
159                         }
160                     }
161                 }
162
163                 final Set<DataSchemaNode> dataNodes = module.getChildNodes();
164                 resolveTypesFromDataSchemaNode(moduleDataTypeBuilder, dataNodes);
165                 return moduleDataTypeBuilder.toInstance();
166             }
167         }
168         return null;
169     }
170
171     private boolean isDerivedFromEnumerationType(
172             final TypeDefinition<?> typeDefinition) {
173         if (typeDefinition != null) {
174             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
175                 return true;
176             } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
177                 return isDerivedFromEnumerationType(typeDefinition
178                         .getBaseType());
179             }
180         }
181         return false;
182     }
183
184     private EnumTypeDefinition enumTypeDefFromExtendedType(
185             final TypeDefinition<?> typeDefinition) {
186         if (typeDefinition != null) {
187             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
188                 return (EnumTypeDefinition) typeDefinition.getBaseType();
189             } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
190                 return enumTypeDefFromExtendedType(typeDefinition.getBaseType());
191             }
192         }
193         return null;
194     }
195
196     private EnumBuilder resolveEnumFromTypeDefinition(
197             final EnumTypeDefinition enumTypeDef, final String enumName,
198             final GeneratedTypeBuilder typeBuilder) {
199         if ((enumTypeDef != null) && (typeBuilder != null)
200                 && (enumTypeDef.getQName() != null)
201                 && (enumTypeDef.getQName().getLocalName() != null)) {
202
203             final String enumerationName = CodeGeneratorHelper
204                     .parseToClassName(enumName);
205             final EnumBuilder enumBuilder = typeBuilder
206                     .addEnumeration(enumerationName);
207
208             if (enumBuilder != null) {
209                 final List<EnumPair> enums = enumTypeDef.getValues();
210                 if (enums != null) {
211                     int listIndex = 0;
212                     for (final EnumPair enumPair : enums) {
213                         if (enumPair != null) {
214                             final String enumPairName = CodeGeneratorHelper
215                                     .parseToClassName(enumPair.getName());
216                             Integer enumPairValue = enumPair.getValue();
217
218                             if (enumPairValue == null) {
219                                 enumPairValue = listIndex;
220                             }
221                             enumBuilder.addValue(enumPairName, enumPairValue);
222                             listIndex++;
223                         }
224                     }
225                 }
226                 return enumBuilder;
227             }
228         }
229         return null;
230     }
231
232     private GeneratedTypeBuilder moduleTypeBuilder(final Module module,
233             final String postfix) {
234         if (module != null) {
235             String packageName = resolveBasePackageName(module.getNamespace(),
236                     module.getYangVersion());
237             final String moduleName = CodeGeneratorHelper
238                     .parseToClassName(module.getName()) + postfix;
239
240             if (packageName != null) {
241                 packageName = validatePackage(packageName);
242                 return new GeneratedTypeBuilderImpl(packageName, moduleName);
243             }
244         }
245         return null;
246     }
247
248     private GeneratedType rpcMethodsToGenType(final Module module) {
249         if (module != null) {
250             final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
251
252             if ((rpcDefinitions != null) && !rpcDefinitions.isEmpty()) {
253                 final GeneratedTypeBuilder rpcTypeBuilder = moduleTypeBuilder(
254                         module, "Rpc");
255
256                 for (final RpcDefinition rpc : rpcDefinitions) {
257                     if (rpc != null) {
258
259                     }
260                 }
261             }
262         }
263         return null;
264     }
265
266     private GeneratedType notifycationsToGenType(final Module module) {
267         if (module != null) {
268             final Set<NotificationDefinition> notifications = module
269                     .getNotifications();
270
271             if ((notifications != null) && !notifications.isEmpty()) {
272                 final GeneratedTypeBuilder notifyTypeBuilder = moduleTypeBuilder(
273                         module, "Notification");
274
275                 for (final NotificationDefinition notification : notifications) {
276                     if (notification != null) {
277
278                     }
279                 }
280             }
281         }
282         return null;
283     }
284
285     private String resolveGeneratedTypePackageName(final SchemaPath schemaPath) {
286         final StringBuilder builder = new StringBuilder();
287         builder.append(basePackageName);
288         if ((schemaPath != null) && (schemaPath.getPath() != null)) {
289             final List<QName> pathToNode = schemaPath.getPath();
290             final int traversalSteps = (pathToNode.size() - 1);
291             for (int i = 0; i < traversalSteps; ++i) {
292                 builder.append(".");
293                 String nodeLocalName = pathToNode.get(i).getLocalName();
294
295                 // TODO: create method
296                 nodeLocalName = nodeLocalName.replace(":", ".");
297                 nodeLocalName = nodeLocalName.replace("-", ".");
298                 builder.append(nodeLocalName);
299             }
300             return validatePackage(builder.toString());
301         }
302         return null;
303     }
304
305     private GeneratedType containerToGenType(ContainerSchemaNode container) {
306         if (container == null) {
307             return null;
308         }
309         final Set<DataSchemaNode> schemaNodes = container.getChildNodes();
310         final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(container);
311
312         resolveTypesFromDataSchemaNode(typeBuilder, schemaNodes);
313         return typeBuilder.toInstance();
314     }
315
316     private GeneratedTypeBuilder resolveTypesFromDataSchemaNode(
317             final GeneratedTypeBuilder typeBuilder,
318             final Set<DataSchemaNode> schemaNodes) {
319
320         if ((schemaNodes != null) && (typeBuilder != null)) {
321             for (final DataSchemaNode node : schemaNodes) {
322                 if (node instanceof LeafSchemaNode) {
323                     resolveLeafSchemaNodeAsMethod(typeBuilder,
324                             (LeafSchemaNode) node);
325                 } else if (node instanceof LeafListSchemaNode) {
326                     resolveLeafListSchemaNode(typeBuilder,
327                             (LeafListSchemaNode) node);
328
329                 } else if (node instanceof ContainerSchemaNode) {
330                     resolveContainerSchemaNode(typeBuilder,
331                             (ContainerSchemaNode) node);
332                 } else if (node instanceof ListSchemaNode) {
333                     resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);
334                 }
335             }
336         }
337         return typeBuilder;
338     }
339
340     private boolean resolveLeafSchemaNodeAsMethod(
341             final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
342         if ((leaf != null) && (typeBuilder != null)) {
343             final String leafName = leaf.getQName().getLocalName();
344             String leafDesc = leaf.getDescription();
345             if (leafDesc == null) {
346                 leafDesc = "";
347             }
348
349             if (leafName != null) {
350                 final TypeDefinition<?> typeDef = leaf.getType();
351
352                 Type type = null;
353                 if (!(typeDef instanceof EnumTypeDefinition)
354                         && !isDerivedFromEnumerationType(typeDef)) {
355                     type = typeProvider
356                             .javaTypeForSchemaDefinitionType(typeDef);
357                 } else {
358                     if (isImported(leaf.getPath(), typeDef.getPath())) {
359                         //TODO: resolving of imported enums as references to GeneratedTypeData interface
360                     } else {
361                         final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
362                         final EnumBuilder enumBuilder = resolveEnumFromTypeDefinition(enumTypeDef, leafName,
363                                 typeBuilder);
364                         
365                         if (enumBuilder != null) {
366                             type = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
367                         }
368                     }
369                 }
370
371                 constructGetter(typeBuilder, leafName, leafDesc, type);
372                 if (!leaf.isConfiguration()) {
373                     constructSetter(typeBuilder, leafName, leafDesc, type);
374                 }
375                 return true;
376             }
377         }
378         return false;
379     }
380
381     private boolean isImported(final SchemaPath leafPath,
382             final SchemaPath typeDefPath) {
383         if ((leafPath != null) && (leafPath.getPath() != null)
384                 && (typeDefPath != null) && (typeDefPath.getPath() != null)) {
385
386             final QName leafPathQName = leafPath.getPath().get(0);
387             final QName typePathQName = typeDefPath.getPath().get(0);
388
389             if ((leafPathQName != null)
390                     && (leafPathQName.getNamespace() != null)
391                     && (typePathQName != null)
392                     && (typePathQName.getNamespace() != null)) {
393                 
394                 return !leafPathQName.getNamespace().equals(
395                         typePathQName.getNamespace());
396             }
397         }
398         return false;
399     }
400
401     private boolean resolveLeafSchemaNodeAsProperty(
402             final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
403             boolean isReadOnly) {
404         if ((leaf != null) && (toBuilder != null)) {
405             final String leafName = leaf.getQName().getLocalName();
406             String leafDesc = leaf.getDescription();
407             if (leafDesc == null) {
408                 leafDesc = "";
409             }
410
411             if (leafName != null) {
412                 final TypeDefinition<?> typeDef = leaf.getType();
413
414                 // TODO: properly resolve enum types
415                 final Type javaType = typeProvider
416                         .javaTypeForSchemaDefinitionType(typeDef);
417
418                 final GeneratedPropertyBuilder propBuilder = toBuilder
419                         .addProperty(CodeGeneratorHelper
420                                 .parseToClassName(leafName));
421
422                 propBuilder.setReadOnly(isReadOnly);
423                 propBuilder.addReturnType(javaType);
424                 propBuilder.addComment(leafDesc);
425
426                 toBuilder.addEqualsIdentity(propBuilder);
427                 toBuilder.addHashIdentity(propBuilder);
428                 toBuilder.addToStringProperty(propBuilder);
429
430                 return true;
431             }
432         }
433         return false;
434     }
435
436     private boolean resolveLeafListSchemaNode(
437             final GeneratedTypeBuilder typeBuilder,
438             final LeafListSchemaNode node) {
439         if ((node != null) && (typeBuilder != null)) {
440             final String nodeName = node.getQName().getLocalName();
441             String nodeDesc = node.getDescription();
442             if (nodeDesc == null) {
443                 nodeDesc = "";
444             }
445
446             if (nodeName != null) {
447                 final TypeDefinition<?> type = node.getType();
448                 final Type listType = Types.listTypeFor(typeProvider
449                         .javaTypeForSchemaDefinitionType(type));
450
451                 constructGetter(typeBuilder, nodeName, nodeDesc, listType);
452                 if (!node.isConfiguration()) {
453                     constructSetter(typeBuilder, nodeName, nodeDesc, listType);
454                 }
455                 return true;
456             }
457         }
458         return false;
459     }
460
461     private boolean resolveContainerSchemaNode(
462             final GeneratedTypeBuilder typeBuilder,
463             final ContainerSchemaNode node) {
464         if ((node != null) && (typeBuilder != null)) {
465             final String nodeName = node.getQName().getLocalName();
466
467             if (nodeName != null) {
468                 final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(node);
469                 constructGetter(typeBuilder, nodeName, "", rawGenType);
470
471                 return true;
472             }
473         }
474         return false;
475     }
476
477     private boolean resolveListSchemaNode(
478             final GeneratedTypeBuilder typeBuilder, final ListSchemaNode node) {
479         if ((node != null) && (typeBuilder != null)) {
480             final String nodeName = node.getQName().getLocalName();
481
482             if (nodeName != null) {
483                 final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(node);
484                 constructGetter(typeBuilder, nodeName, "",
485                         Types.listTypeFor(rawGenType));
486                 if (!node.isConfiguration()) {
487                     constructSetter(typeBuilder, nodeName, "",
488                             Types.listTypeFor(rawGenType));
489                 }
490                 return true;
491             }
492         }
493         return false;
494     }
495
496     private GeneratedTypeBuilder addRawInterfaceDefinition(
497             final DataSchemaNode schemaNode) {
498         if (schemaNode == null) {
499             return null;
500         }
501
502         final String packageName = resolveGeneratedTypePackageName(schemaNode
503                 .getPath());
504         final String schemaNodeName = schemaNode.getQName().getLocalName();
505
506         if ((packageName != null) && (schemaNode != null)
507                 && (schemaNodeName != null)) {
508             final String genTypeName = CodeGeneratorHelper
509                     .parseToClassName(schemaNodeName);
510             final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(
511                     packageName, genTypeName);
512
513             if (!genTypeBuilders.containsKey(packageName)) {
514                 final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();
515                 builders.put(genTypeName, newType);
516                 genTypeBuilders.put(packageName, builders);
517             } else {
518                 final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders
519                         .get(packageName);
520                 if (!builders.containsKey(genTypeName)) {
521                     builders.put(genTypeName, newType);
522                 }
523             }
524             return newType;
525         }
526         return null;
527     }
528
529     private String getterMethodName(final String methodName) {
530         final StringBuilder method = new StringBuilder();
531         method.append("get");
532         method.append(CodeGeneratorHelper.parseToClassName(methodName));
533         return method.toString();
534     }
535
536     private String setterMethodName(final String methodName) {
537         final StringBuilder method = new StringBuilder();
538         method.append("set");
539         method.append(CodeGeneratorHelper.parseToClassName(methodName));
540         return method.toString();
541     }
542
543     private MethodSignatureBuilder constructGetter(
544             final GeneratedTypeBuilder interfaceBuilder,
545             final String schemaNodeName, final String comment,
546             final Type returnType) {
547         final MethodSignatureBuilder getMethod = interfaceBuilder
548                 .addMethod(getterMethodName(schemaNodeName));
549
550         getMethod.addComment(comment);
551         getMethod.addReturnType(returnType);
552
553         return getMethod;
554     }
555
556     private MethodSignatureBuilder constructSetter(
557             final GeneratedTypeBuilder interfaceBuilder,
558             final String schemaNodeName, final String comment,
559             final Type parameterType) {
560         final MethodSignatureBuilder setMethod = interfaceBuilder
561                 .addMethod(setterMethodName(schemaNodeName));
562
563         setMethod.addComment(comment);
564         setMethod.addParameter(parameterType,
565                 CodeGeneratorHelper.parseToParamName(schemaNodeName));
566         setMethod.addReturnType(Types.voidType());
567
568         return setMethod;
569     }
570
571     private String resolveBasePackageName(final URI moduleNamespace,
572             final String yangVersion) {
573         final StringBuilder packageNameBuilder = new StringBuilder();
574
575         packageNameBuilder.append("org.opendaylight.yang.gen.v");
576         packageNameBuilder.append(yangVersion);
577         packageNameBuilder.append(".rev");
578         packageNameBuilder.append(calendar.get(Calendar.YEAR));
579         packageNameBuilder.append((calendar.get(Calendar.MONTH) + 1));
580         packageNameBuilder.append(calendar.get(Calendar.DAY_OF_MONTH));
581         packageNameBuilder.append(".");
582
583         String namespace = moduleNamespace.toString();
584         namespace = namespace.replace(":", ".");
585         namespace = namespace.replace("-", ".");
586
587         packageNameBuilder.append(namespace);
588
589         return packageNameBuilder.toString();
590     }
591
592     private List<Type> listToGenType(final ListSchemaNode list) {
593         if (list == null) {
594             return null;
595         }
596         final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(list);
597         final List<String> listKeys = listKeys(list);
598         GeneratedTOBuilder genTOBuilder = null;
599         if (listKeys.size() > 0) {
600             genTOBuilder = resolveListKey(list);
601         }
602
603         final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
604         for (final DataSchemaNode node : schemaNodes) {
605
606             if (node instanceof LeafSchemaNode) {
607                 final LeafSchemaNode leaf = (LeafSchemaNode) node;
608                 if (!isPartOfListKey(leaf, listKeys)) {
609                     resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
610                 } else {
611                     resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
612                 }
613             } else if (node instanceof LeafListSchemaNode) {
614                 resolveLeafListSchemaNode(typeBuilder,
615                         (LeafListSchemaNode) node);
616             } else if (node instanceof ContainerSchemaNode) {
617                 resolveContainerSchemaNode(typeBuilder,
618                         (ContainerSchemaNode) node);
619             } else if (node instanceof ListSchemaNode) {
620                 resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);
621             }
622         }
623
624         final List<Type> genTypes = new ArrayList<Type>();
625         if (genTOBuilder != null) {
626             final GeneratedTransferObject genTO = genTOBuilder.toInstance();
627             constructGetter(typeBuilder, genTO.getName(),
628                     "Returns Primary Key of Yang List Type", genTO);
629             genTypes.add(genTO);
630         }
631         genTypes.add(typeBuilder.toInstance());
632         return genTypes;
633     }
634
635     /**
636      * @param list
637      * @return
638      */
639     private GeneratedTOBuilder resolveListKey(final ListSchemaNode list) {
640         final String packageName = resolveGeneratedTypePackageName(list
641                 .getPath());
642         final String listName = list.getQName().getLocalName() + "Key";
643
644         if ((packageName != null) && (list != null) && (listName != null)) {
645             final String genTOName = CodeGeneratorHelper
646                     .parseToClassName(listName);
647             final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(
648                     packageName, genTOName);
649
650             return newType;
651         }
652         return null;
653     }
654
655     private boolean isPartOfListKey(final LeafSchemaNode leaf,
656             final List<String> keys) {
657         if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
658             final String leafName = leaf.getQName().getLocalName();
659             if (keys.contains(leafName)) {
660                 return true;
661             }
662         }
663         return false;
664     }
665
666     private List<String> listKeys(final ListSchemaNode list) {
667         final List<String> listKeys = new ArrayList<String>();
668
669         if (list.getKeyDefinition() != null) {
670             final List<QName> keyDefinitions = list.getKeyDefinition();
671
672             for (final QName keyDefinition : keyDefinitions) {
673                 listKeys.add(keyDefinition.getLocalName());
674             }
675         }
676         return listKeys;
677     }
678
679     private GeneratedTypeBuilder resolveListTypeBuilder(
680             final ListSchemaNode list) {
681         final String packageName = resolveGeneratedTypePackageName(list
682                 .getPath());
683         final String schemaNodeName = list.getQName().getLocalName();
684         final String genTypeName = CodeGeneratorHelper
685                 .parseToClassName(schemaNodeName);
686
687         GeneratedTypeBuilder typeBuilder = null;
688         if (genTypeBuilders.containsKey(packageName)) {
689             final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();
690             typeBuilder = builders.get(genTypeName);
691
692             if (null == typeBuilder) {
693                 typeBuilder = addRawInterfaceDefinition(list);
694             }
695         }
696         return typeBuilder;
697     }
698 }