Merge "Bug fix for ForwardingRulesManager: addFlow and addFlowAsync are reversed."
[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.BindingGeneratorUtil;
22 import org.opendaylight.controller.binding.generator.util.Types;
23 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
24 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
25 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
26 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
27 import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
28 import org.opendaylight.controller.sal.binding.model.api.Type;
29 import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;
30 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
31 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
32 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
33 import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder;
34 import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
35 import org.opendaylight.controller.yang.common.QName;
36 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
37 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
38 import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
39 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
40 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
41 import org.opendaylight.controller.yang.model.api.Module;
42 import org.opendaylight.controller.yang.model.api.NotificationDefinition;
43 import org.opendaylight.controller.yang.model.api.RpcDefinition;
44 import org.opendaylight.controller.yang.model.api.SchemaContext;
45 import org.opendaylight.controller.yang.model.api.SchemaPath;
46 import org.opendaylight.controller.yang.model.api.TypeDefinition;
47 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
48 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
49 import org.opendaylight.controller.yang.model.util.DataNodeIterator;
50 import org.opendaylight.controller.yang.model.util.ExtendedType;
51
52 public class BindingGeneratorImpl implements BindingGenerator {
53
54     private static final String[] SET_VALUES = new String[] { "abstract",
55             "assert", "boolean", "break", "byte", "case", "catch", "char",
56             "class", "const", "continue", "default", "double", "do", "else",
57             "enum", "extends", "false", "final", "finally", "float", "for",
58             "goto", "if", "implements", "import", "instanceof", "int",
59             "interface", "long", "native", "new", "null", "package", "private",
60             "protected", "public", "return", "short", "static", "strictfp",
61             "super", "switch", "synchronized", "this", "throw", "throws",
62             "transient", "true", "try", "void", "volatile", "while" };
63
64     public static final Set<String> JAVA_RESERVED_WORDS = new HashSet<String>(
65             Arrays.asList(SET_VALUES));
66
67     private static Calendar calendar = new GregorianCalendar();
68     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
69     private TypeProvider typeProvider;
70     private String basePackageName;
71
72     public BindingGeneratorImpl() {
73         super();
74     }
75
76     private static String validatePackage(final String packageName) {
77         if (packageName != null) {
78             final String[] packNameParts = packageName.split("\\.");
79             if (packNameParts != null) {
80                 final StringBuilder builder = new StringBuilder();
81                 for (int i = 0; i < packNameParts.length; ++i) {
82                     if (JAVA_RESERVED_WORDS.contains(packNameParts[i])) {
83                         packNameParts[i] = "_" + packNameParts[i];
84                     }
85                     if (i > 0) {
86                         builder.append(".");
87                     }
88                     builder.append(packNameParts[i]);
89                 }
90                 return builder.toString();
91             }
92         }
93         return packageName;
94     }
95
96     @Override
97     public List<Type> generateTypes(final SchemaContext context) {
98         final List<Type> genTypes = new ArrayList<Type>();
99
100         if (context != null) {
101             typeProvider = new TypeProviderImpl(context);
102             final Set<Module> modules = context.getModules();
103             
104             if (modules != null) {
105                 for (final Module module : modules) {
106                     final DataNodeIterator moduleIterator = new DataNodeIterator(
107                             module);
108
109                     genTypeBuilders = new HashMap<String, Map<String, GeneratedTypeBuilder>>();
110                     final List<ContainerSchemaNode> schemaContainers = moduleIterator
111                             .allContainers();
112                     final List<ListSchemaNode> schemaLists = moduleIterator
113                             .allLists();
114
115                     basePackageName = BindingGeneratorUtil
116                             .moduleNamespaceToPackageName(
117                                     module.getNamespace(),
118                                     module.getYangVersion());
119
120                     if (schemaContainers.size() > 0) {
121                         for (final ContainerSchemaNode container : schemaContainers) {
122                             genTypes.add(containerToGenType(container));
123                         }
124                     }
125                     if (schemaLists.size() > 0) {
126                         for (final ListSchemaNode list : schemaLists) {
127                             genTypes.addAll(listToGenType(list));
128                         }
129                     }
130
131                     final GeneratedType genDataType = moduleToDataType(module);
132                     final GeneratedType genRpcType = rpcMethodsToGenType(module);
133                     final GeneratedType genNotifyType = notifycationsToGenType(module);
134
135                     if (genDataType != null) {
136                         genTypes.add(genDataType);
137                     }
138                     if (genRpcType != null) {
139                         genTypes.add(genRpcType);
140                     }
141                     if (genNotifyType != null) {
142                         genTypes.add(genNotifyType);
143                     }
144                 }
145                 
146                 //FIXME this is quick add of typedefs to generated types from type provider
147                 genTypes.addAll(((TypeProviderImpl)typeProvider).getGeneratedTypeDefs());
148             }
149         }
150         return genTypes;
151     }
152
153     private GeneratedType moduleToDataType(final Module module) {
154         if (module != null) {
155             final Set<TypeDefinition<?>> typeDefinitions = module
156                     .getTypeDefinitions();
157             final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(
158                     module, "Data");
159
160             if (moduleDataTypeBuilder != null) {
161                 if (typeDefinitions != null) {
162                     for (final TypeDefinition<?> typedef : typeDefinitions) {
163                         if (isDerivedFromEnumerationType(typedef)) {
164                             final EnumTypeDefinition enumBaseType = enumTypeDefFromExtendedType(typedef);
165                             resolveEnumFromTypeDefinition(enumBaseType, typedef
166                                     .getQName().getLocalName(),
167                                     moduleDataTypeBuilder);
168                         }
169                     }
170                 }
171
172                 final Set<DataSchemaNode> dataNodes = module.getChildNodes();
173                 resolveTypesFromDataSchemaNode(moduleDataTypeBuilder, dataNodes);
174                 return moduleDataTypeBuilder.toInstance();
175             }
176         }
177         return null;
178     }
179
180     private boolean isDerivedFromEnumerationType(
181             final TypeDefinition<?> typeDefinition) {
182         if (typeDefinition != null) {
183             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
184                 return true;
185             } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
186                 return isDerivedFromEnumerationType(typeDefinition
187                         .getBaseType());
188             }
189         }
190         return false;
191     }
192
193     private EnumTypeDefinition enumTypeDefFromExtendedType(
194             final TypeDefinition<?> typeDefinition) {
195         if (typeDefinition != null) {
196             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
197                 return (EnumTypeDefinition) typeDefinition.getBaseType();
198             } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
199                 return enumTypeDefFromExtendedType(typeDefinition.getBaseType());
200             }
201         }
202         return null;
203     }
204
205     private EnumBuilder resolveEnumFromTypeDefinition(
206             final EnumTypeDefinition enumTypeDef, final String enumName,
207             final GeneratedTypeBuilder typeBuilder) {
208         if ((enumTypeDef != null) && (typeBuilder != null)
209                 && (enumTypeDef.getQName() != null)
210                 && (enumTypeDef.getQName().getLocalName() != null)) {
211
212             final String enumerationName = BindingGeneratorUtil
213                     .parseToClassName(enumName);
214             final EnumBuilder enumBuilder = typeBuilder
215                     .addEnumeration(enumerationName);
216
217             if (enumBuilder != null) {
218                 final List<EnumPair> enums = enumTypeDef.getValues();
219                 if (enums != null) {
220                     int listIndex = 0;
221                     for (final EnumPair enumPair : enums) {
222                         if (enumPair != null) {
223                             final String enumPairName = BindingGeneratorUtil
224                                     .parseToClassName(enumPair.getName());
225                             Integer enumPairValue = enumPair.getValue();
226
227                             if (enumPairValue == null) {
228                                 enumPairValue = listIndex;
229                             }
230                             enumBuilder.addValue(enumPairName, enumPairValue);
231                             listIndex++;
232                         }
233                     }
234                 }
235                 return enumBuilder;
236             }
237         }
238         return null;
239     }
240
241     private GeneratedTypeBuilder moduleTypeBuilder(final Module module,
242             final String postfix) {
243         if (module != null) {
244             String packageName = resolveBasePackageName(module.getNamespace(),
245                     module.getYangVersion());
246             final String moduleName = BindingGeneratorUtil
247                     .parseToClassName(module.getName()) + postfix;
248
249             if (packageName != null) {
250                 packageName = validatePackage(packageName);
251                 return new GeneratedTypeBuilderImpl(packageName, moduleName);
252             }
253         }
254         return null;
255     }
256
257     private GeneratedType rpcMethodsToGenType(final Module module) {
258         if (module != null) {
259             final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
260             //TODO: add implementation
261             if ((rpcDefinitions != null) && !rpcDefinitions.isEmpty()) {
262                 final GeneratedTypeBuilder rpcTypeBuilder = moduleTypeBuilder(
263                         module, "Rpc");
264
265                 for (final RpcDefinition rpc : rpcDefinitions) {
266                     if (rpc != null) {
267
268                     }
269                 }
270             }
271         }
272         return null;
273     }
274
275     private GeneratedType notifycationsToGenType(final Module module) {
276         if (module != null) {
277             final Set<NotificationDefinition> notifications = module
278                     .getNotifications();
279             //TODO: add implementation
280             if ((notifications != null) && !notifications.isEmpty()) {
281                 final GeneratedTypeBuilder notifyTypeBuilder = moduleTypeBuilder(
282                         module, "Notification");
283
284                 for (final NotificationDefinition notification : notifications) {
285                     if (notification != null) {
286
287                     }
288                 }
289             }
290         }
291         return null;
292     }
293     
294     private List<GeneratedType> augmentationToGenTypes(final Module module) {
295         final List<GeneratedType> augmentGenTypes = new ArrayList<GeneratedType>();
296         
297         //TODO: add implementation
298         
299         return augmentGenTypes;
300     }
301     
302     private GeneratedType containerToGenType(ContainerSchemaNode container) {
303         if (container == null) {
304             return null;
305         }
306         final Set<DataSchemaNode> schemaNodes = container.getChildNodes();
307         final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(container);
308
309         resolveTypesFromDataSchemaNode(typeBuilder, schemaNodes);
310         return typeBuilder.toInstance();
311     }
312
313     private GeneratedTypeBuilder resolveTypesFromDataSchemaNode(
314             final GeneratedTypeBuilder typeBuilder,
315             final Set<DataSchemaNode> schemaNodes) {
316
317         if ((schemaNodes != null) && (typeBuilder != null)) {
318             for (final DataSchemaNode node : schemaNodes) {
319                 if (node instanceof LeafSchemaNode) {
320                     resolveLeafSchemaNodeAsMethod(typeBuilder,
321                             (LeafSchemaNode) node);
322                 } else if (node instanceof LeafListSchemaNode) {
323                     resolveLeafListSchemaNode(typeBuilder,
324                             (LeafListSchemaNode) node);
325
326                 } else if (node instanceof ContainerSchemaNode) {
327                     resolveContainerSchemaNode(typeBuilder,
328                             (ContainerSchemaNode) node);
329                 } else if (node instanceof ListSchemaNode) {
330                     resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);
331                 }
332             }
333         }
334         return typeBuilder;
335     }
336
337     private boolean resolveLeafSchemaNodeAsMethod(
338             final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
339         if ((leaf != null) && (typeBuilder != null)) {
340             final String leafName = leaf.getQName().getLocalName();
341             String leafDesc = leaf.getDescription();
342             if (leafDesc == null) {
343                 leafDesc = "";
344             }
345
346             if (leafName != null) {
347                 final TypeDefinition<?> typeDef = leaf.getType();
348
349                 Type type = null;
350                 if (!(typeDef instanceof EnumTypeDefinition)
351                         && !isDerivedFromEnumerationType(typeDef)) {
352                     type = typeProvider
353                             .javaTypeForSchemaDefinitionType(typeDef);
354                 } else {
355                     if (isImported(leaf.getPath(), typeDef.getPath())) {
356                         // TODO: resolving of imported enums as references to
357                         // GeneratedTypeData interface
358                     } else {
359                         final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
360                         final EnumBuilder enumBuilder = resolveEnumFromTypeDefinition(
361                                 enumTypeDef, leafName, typeBuilder);
362
363                         if (enumBuilder != null) {
364                             type = new ReferencedTypeImpl(
365                                     enumBuilder.getPackageName(),
366                                     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(BindingGeneratorUtil
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 = BindingGeneratorUtil
503                 .packageNameForGeneratedType(basePackageName,
504                         schemaNode.getPath());
505         final String schemaNodeName = schemaNode.getQName().getLocalName();
506
507         if ((packageName != null) && (schemaNode != null)
508                 && (schemaNodeName != null)) {
509             final String genTypeName = BindingGeneratorUtil
510                     .parseToClassName(schemaNodeName);
511             final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(
512                     packageName, genTypeName);
513
514             if (!genTypeBuilders.containsKey(packageName)) {
515                 final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();
516                 builders.put(genTypeName, newType);
517                 genTypeBuilders.put(packageName, builders);
518             } else {
519                 final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders
520                         .get(packageName);
521                 if (!builders.containsKey(genTypeName)) {
522                     builders.put(genTypeName, newType);
523                 }
524             }
525             return newType;
526         }
527         return null;
528     }
529
530     private String getterMethodName(final String methodName) {
531         final StringBuilder method = new StringBuilder();
532         method.append("get");
533         method.append(BindingGeneratorUtil.parseToClassName(methodName));
534         return method.toString();
535     }
536
537     private String setterMethodName(final String methodName) {
538         final StringBuilder method = new StringBuilder();
539         method.append("set");
540         method.append(BindingGeneratorUtil.parseToClassName(methodName));
541         return method.toString();
542     }
543
544     private MethodSignatureBuilder constructGetter(
545             final GeneratedTypeBuilder interfaceBuilder,
546             final String schemaNodeName, final String comment,
547             final Type returnType) {
548         final MethodSignatureBuilder getMethod = interfaceBuilder
549                 .addMethod(getterMethodName(schemaNodeName));
550
551         getMethod.addComment(comment);
552         getMethod.addReturnType(returnType);
553
554         return getMethod;
555     }
556
557     private MethodSignatureBuilder constructSetter(
558             final GeneratedTypeBuilder interfaceBuilder,
559             final String schemaNodeName, final String comment,
560             final Type parameterType) {
561         final MethodSignatureBuilder setMethod = interfaceBuilder
562                 .addMethod(setterMethodName(schemaNodeName));
563
564         setMethod.addComment(comment);
565         setMethod.addParameter(parameterType,
566                 BindingGeneratorUtil.parseToValidParamName(schemaNodeName));
567         setMethod.addReturnType(Types.voidType());
568
569         return setMethod;
570     }
571
572     private String resolveBasePackageName(final URI moduleNamespace,
573             final String yangVersion) {
574         final StringBuilder packageNameBuilder = new StringBuilder();
575
576         packageNameBuilder.append("org.opendaylight.yang.gen.v");
577         packageNameBuilder.append(yangVersion);
578         packageNameBuilder.append(".rev");
579         packageNameBuilder.append(calendar.get(Calendar.YEAR));
580         packageNameBuilder.append((calendar.get(Calendar.MONTH) + 1));
581         packageNameBuilder.append(calendar.get(Calendar.DAY_OF_MONTH));
582         packageNameBuilder.append(".");
583
584         String namespace = moduleNamespace.toString();
585         namespace = namespace.replace(":", ".");
586         namespace = namespace.replace("-", ".");
587
588         packageNameBuilder.append(namespace);
589
590         return packageNameBuilder.toString();
591     }
592
593     private List<Type> listToGenType(final ListSchemaNode list) {
594         if (list == null) {
595             return null;
596         }
597         final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(list);
598         final List<String> listKeys = listKeys(list);
599         GeneratedTOBuilder genTOBuilder = null;
600         if (listKeys.size() > 0) {
601             genTOBuilder = resolveListKey(list);
602         }
603
604         final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
605         for (final DataSchemaNode node : schemaNodes) {
606
607             if (node instanceof LeafSchemaNode) {
608                 final LeafSchemaNode leaf = (LeafSchemaNode) node;
609                 if (!isPartOfListKey(leaf, listKeys)) {
610                     resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
611                 } else {
612                     resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
613                 }
614             } else if (node instanceof LeafListSchemaNode) {
615                 resolveLeafListSchemaNode(typeBuilder,
616                         (LeafListSchemaNode) node);
617             } else if (node instanceof ContainerSchemaNode) {
618                 resolveContainerSchemaNode(typeBuilder,
619                         (ContainerSchemaNode) node);
620             } else if (node instanceof ListSchemaNode) {
621                 resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);
622             }
623         }
624
625         final List<Type> genTypes = new ArrayList<Type>();
626         if (genTOBuilder != null) {
627             final GeneratedTransferObject genTO = genTOBuilder.toInstance();
628             constructGetter(typeBuilder, genTO.getName(),
629                     "Returns Primary Key of Yang List Type", genTO);
630             genTypes.add(genTO);
631         }
632         genTypes.add(typeBuilder.toInstance());
633         return genTypes;
634     }
635
636     /**
637      * @param list
638      * @return
639      */
640     private GeneratedTOBuilder resolveListKey(final ListSchemaNode list) {
641         final String packageName = BindingGeneratorUtil
642                 .packageNameForGeneratedType(basePackageName, list.getPath());
643         final String listName = list.getQName().getLocalName() + "Key";
644
645         return BindingGeneratorUtil.schemaNodeToTransferObjectBuilder(
646                 packageName, list, listName);
647     }
648
649     private boolean isPartOfListKey(final LeafSchemaNode leaf,
650             final List<String> keys) {
651         if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
652             final String leafName = leaf.getQName().getLocalName();
653             if (keys.contains(leafName)) {
654                 return true;
655             }
656         }
657         return false;
658     }
659
660     private List<String> listKeys(final ListSchemaNode list) {
661         final List<String> listKeys = new ArrayList<String>();
662
663         if (list.getKeyDefinition() != null) {
664             final List<QName> keyDefinitions = list.getKeyDefinition();
665
666             for (final QName keyDefinition : keyDefinitions) {
667                 listKeys.add(keyDefinition.getLocalName());
668             }
669         }
670         return listKeys;
671     }
672
673     private GeneratedTypeBuilder resolveListTypeBuilder(
674             final ListSchemaNode list) {
675         final String packageName = BindingGeneratorUtil
676                 .packageNameForGeneratedType(basePackageName,
677                         list.getPath());
678         final String schemaNodeName = list.getQName().getLocalName();
679         final String genTypeName = BindingGeneratorUtil
680                 .parseToClassName(schemaNodeName);
681
682         GeneratedTypeBuilder typeBuilder = null;
683         if (genTypeBuilders.containsKey(packageName)) {
684             final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();
685             typeBuilder = builders.get(genTypeName);
686
687             if (null == typeBuilder) {
688                 typeBuilder = addRawInterfaceDefinition(list);
689             }
690         }
691         return typeBuilder;
692     }
693 }