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