Added support for yang-ext:context-reference extension.
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingGeneratorImpl.xtend
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.yangtools.sal.binding.generator.impl;\r
9 \r
10 import java.util.ArrayList;\r
11 import java.util.Collections;\r
12 import java.util.HashMap;\r
13 import java.util.List;\r
14 import java.util.Map;\r
15 import java.util.Set;\r
16 import org.opendaylight.yangtools.binding.generator.util.BindingTypes;\r
17 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;\r
18 import org.opendaylight.yangtools.binding.generator.util.Types;\r
19 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;\r
20 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;\r
21 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;\r
22 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;\r
23 import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier;\r
24 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;\r
25 import org.opendaylight.yangtools.sal.binding.model.api.Type;\r
26 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;\r
27 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;\r
28 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;\r
29 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder;\r
30 import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort;\r
31 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;\r
32 import org.opendaylight.yangtools.yang.binding.RpcService;\r
33 import org.opendaylight.yangtools.yang.common.RpcResult;\r
34 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;\r
35 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;\r
36 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;\r
37 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;\r
38 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;\r
39 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;\r
40 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;\r
41 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;\r
42 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;\r
43 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;\r
44 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;\r
45 import org.opendaylight.yangtools.yang.model.api.Module;\r
46 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;\r
47 import org.opendaylight.yangtools.yang.model.api.SchemaContext;\r
48 import org.opendaylight.yangtools.yang.model.api.SchemaNode;\r
49 import org.opendaylight.yangtools.yang.model.api.SchemaPath;\r
50 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;\r
51 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;\r
52 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;\r
53 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;\r
54 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;\r
55 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;\r
56 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;\r
57 import org.opendaylight.yangtools.yang.model.util.UnionType;\r
58 import static com.google.common.base.Preconditions.*;\r
59 import static extension org.opendaylight.yangtools.binding.generator.util.Types.*;\r
60 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;\r
61 import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*;\r
62 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;\r
63 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort\r
64 import org.opendaylight.yangtools.yang.model.util.ExtendedType;\rimport org.opendaylight.yangtools.yang.common.QName
65 import org.opendaylight.yangtools.yang.model.api.UsesNode
66 import java.util.HashSet
67 import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext
68 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder
69 import org.opendaylight.yangtools.yang.model.api.ModuleImport
70 import org.opendaylight.yangtools.yang.binding.DataContainer
71
72 public class BindingGeneratorImpl implements BindingGenerator {\r
73     /**\r
74      * Outter key represents the package name. Outter value represents map of\r
75      * all builders in the same package. Inner key represents the schema node\r
76      * name (in JAVA class/interface name format). Inner value represents\r
77      * instance of builder for schema node specified in key part.\r
78      */\r
79     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;\r
80 \r
81     /**\r
82      * Provide methods for converting YANG types to JAVA types.\r
83      */\r
84     private var TypeProvider typeProvider;\r
85 \r
86     /**\r
87      * Holds reference to schema context to resolve data of augmented elemnt\r
88      * when creating augmentation builder\r
89      */\r
90     private var SchemaContext schemaContext;\r
91 \r
92     /**\r
93      * Each grouping which is converted from schema node to generated type is\r
94      * added to this map with its Schema path as key to make it easier to get\r
95      * reference to it. In schema nodes in <code>uses</code> attribute there is\r
96      * only Schema Path but when building list of implemented interfaces for\r
97      * Schema node the object of type <code>Type</code> is required. So in this\r
98      * case is used this map.\r
99      */\r
100     private val allGroupings = new HashMap<SchemaPath, GeneratedType>();\r
101 \r
102     private val yangToJavaMapping = new HashMap<SchemaPath, Type>();\r
103 \r
104     /**\r
105      * Constant with the concrete name of namespace.\r
106      */\r
107     private val static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext";\r
108 \r
109     /**\r
110      * Constant with the concrete name of identifier.\r
111      */\r
112     private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier";\r
113 \r
114     /**\r
115      * Resolves generated types from <code>context</code> schema nodes of all\r
116      * modules.\r
117      *\r
118      * Generated types are created for modules, groupings, types, containers,\r
119      * lists, choices, augments, rpcs, notification, identities.\r
120      *\r
121      * @param context\r
122      *            schema context which contains data about all schema nodes\r
123      *            saved in modules\r
124      * @return list of types (usually <code>GeneratedType</code>\r
125      *         <code>GeneratedTransferObject</code>which are generated from\r
126      *         <code>context</code> data.\r
127      * @throws IllegalArgumentException\r
128      *             if param <code>context</code> is null\r
129      * @throws IllegalStateException\r
130      *             if <code>context</code> contain no modules\r
131      */\r
132     override generateTypes(SchemaContext context) {\r
133         checkArgument(context !== null, "Schema Context reference cannot be NULL.");\r
134         checkState(context.modules !== null, "Schema Context does not contain defined modules.");\r
135         schemaContext = context;\r
136         typeProvider = new TypeProviderImpl(context);\r
137         val Set<Module> modules = context.modules;\r
138         return generateTypes(context, modules);\r
139     }\r
140 \r
141     /**\r
142      * Resolves generated types from <code>context</code> schema nodes only for\r
143      * modules specified in <code>modules</code>\r
144      *\r
145      * Generated types are created for modules, groupings, types, containers,\r
146      * lists, choices, augments, rpcs, notification, identities.\r
147      *\r
148      * @param context\r
149      *            schema context which contains data about all schema nodes\r
150      *            saved in modules\r
151      * @param modules\r
152      *            set of modules for which schema nodes should be generated\r
153      *            types\r
154      * @return list of types (usually <code>GeneratedType</code> or\r
155      *         <code>GeneratedTransferObject</code>) which:\r
156      *         <ul>\r
157      *         <li>are generated from <code>context</code> schema nodes and</li>\r
158      *         <li>are also part of some of the module in <code>modules</code>\r
159      *         set</li>.\r
160      *         </ul>\r
161      * @throws IllegalArgumentException\r
162      *             <ul>\r
163      *             <li>if param <code>context</code> is null or</li>\r
164      *             <li>if param <code>modules</code> is null</li>\r
165      *             </ul>\r
166      * @throws IllegalStateException\r
167      *             if <code>context</code> contain no modules\r
168      */\r
169     override generateTypes(SchemaContext context, Set<Module> modules) {\r
170         checkArgument(context !== null, "Schema Context reference cannot be NULL.");\r
171         checkState(context.modules !== null, "Schema Context does not contain defined modules.");\r
172         checkArgument(modules !== null, "Set of Modules cannot be NULL.");\r
173 \r
174         val List<Type> filteredGenTypes = new ArrayList();\r
175 \r
176         schemaContext = context;\r
177         typeProvider = new TypeProviderImpl(context);\r
178         val contextModules = ModuleDependencySort.sort(context.modules);\r
179         genTypeBuilders = new HashMap();\r
180 \r
181         for (contextModule : contextModules) {\r
182             val List<Type> generatedTypes = new ArrayList();\r
183             generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule));\r
184             generatedTypes.addAll(allGroupingsToGenTypes(contextModule));\r
185             if(false == contextModule.childNodes.isEmpty()) {\r
186                 generatedTypes.add(moduleToDataType(contextModule));\r
187             }\r
188             generatedTypes.addAll(allContainersToGenTypes(contextModule));\r
189             generatedTypes.addAll(allListsToGenTypes(contextModule));\r
190             generatedTypes.addAll(allChoicesToGenTypes(contextModule));\r
191             generatedTypes.addAll(allRPCMethodsToGenType(contextModule));\r
192             generatedTypes.addAll(allNotificationsToGenType(contextModule));\r
193             generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context));\r
194 \r
195             if(modules.contains(contextModule)) {\r
196                 filteredGenTypes.addAll(generatedTypes);\r
197             }\r
198         }\r
199         for (contextModule : contextModules) {\r
200             val generatedTypes = (allAugmentsToGenTypes(contextModule));\r
201             if(modules.contains(contextModule)) {\r
202                 filteredGenTypes.addAll(generatedTypes);\r
203             }\r
204 \r
205         }\r
206         return filteredGenTypes;\r
207     }\r
208 \r
209     /**\r
210      * Converts all extended type definitions of module to the list of\r
211      * <code>Type</code> objects.\r
212      *\r
213      * @param module\r
214      *            module from which is obtained set of type definitions\r
215      * @return list of <code>Type</code> which are generated from extended\r
216      *         definition types (object of type <code>ExtendedType</code>)\r
217      * @throws IllegalArgumentException\r
218      *             <ul>\r
219      *             <li>if module equals null</li>\r
220      *             <li>if name of module equals null</li>\r
221      *             <li>if type definitions of module equal null</li>\r
222      *             </ul>\r
223      *\r
224      */\r
225     private def List<Type> allTypeDefinitionsToGenTypes(Module module) {\r
226         checkArgument(module !== null, "Module reference cannot be NULL.");\r
227         checkArgument(module.name !== null, "Module name cannot be NULL.");\r
228         val Set<TypeDefinition<?>> typeDefinitions = module.typeDefinitions;\r
229         checkState(typeDefinitions !== null, '''Type Definitions for module Â«module.name» cannot be NULL.''');\r
230 \r
231         val List<Type> generatedTypes = new ArrayList();\r
232         for (TypeDefinition<?> typedef : typeDefinitions) {\r
233             if(typedef !== null) {\r
234                 val type = (typeProvider as TypeProviderImpl).generatedTypeForExtendedDefinitionType(typedef, typedef);\r
235                 if((type !== null) && !generatedTypes.contains(type)) {\r
236                     generatedTypes.add(type);\r
237                 }\r
238             }\r
239         }\r
240         return generatedTypes;\r
241     }\r
242     \r
243     private def List<Type> dataNodeContainerToGenType(String basePackageName, DataNodeContainer node, Module module) {\r
244         if (node === null) {\r
245             return null;\r
246         }\r
247         if (!(node instanceof SchemaNode)) {\r
248             throw new IllegalArgumentException("node to generate must be instance of SchemaNode");\r
249         }\r
250         val List<Type> result = new ArrayList();\r
251 \r
252         result.addAll(processUsesAugments(node, module));\r
253 \r
254         val packageName = packageNameForGeneratedType(basePackageName, (node as SchemaNode).path);\r
255         val typeBuilder = addDefaultInterfaceDefinition(packageName, node as SchemaNode);\r
256         val schemaNodes = node.childNodes;\r
257         if (node instanceof ContainerSchemaNode) {\r
258             resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);\r
259             result.add(typeBuilder.toInstance());\r
260         } else if (node instanceof ListSchemaNode) {\r
261             val List<String> listKeys = listKeys(node as ListSchemaNode);\r
262             val genTOBuilder = resolveListKeyTOBuilder(packageName, node as ListSchemaNode);\r
263 \r
264             if(genTOBuilder !== null) {\r
265                 val identifierMarker = IDENTIFIER.parameterizedTypeFor(typeBuilder);\r
266                 val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder);\r
267                 genTOBuilder.addImplementsType(identifierMarker);\r
268                 typeBuilder.addImplementsType(identifiableMarker);\r
269             }\r
270             for (schemaNode : schemaNodes) {\r
271                 if (!schemaNode.isAugmenting()) {\r
272                     addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys);\r
273                 }\r
274             }\r
275             result.addAll(typeBuildersToGenTypes(typeBuilder, genTOBuilder));\r
276         }\r
277         \r
278         return result;\r
279     }\r
280 \r
281     private def List<Type> processUsesAugments(DataNodeContainer node, Module module) {\r
282         val List<Type> result = new ArrayList();\r
283         val basePackageName = moduleNamespaceToPackageName(module);\r
284 \r
285         for (usesNode : node.uses) {\r
286             for (augment : usesNode.augmentations) {\r
287                 result.addAll(augmentationToGenTypes(basePackageName, augment, module, true));\r
288                 result.addAll(processUsesAugments(augment, module));\r
289             }\r
290         }\r
291 \r
292         return result;\r
293     }\r
294 \r
295     /**\r
296      * Converts all <b>containers</b> of the module to the list of\r
297      * <code>Type</code> objects.\r
298      *\r
299      * @param module\r
300      *            module from which is obtained DataNodeIterator to iterate over\r
301      *            all containers\r
302      * @return list of <code>Type</code> which are generated from containers\r
303      *         (objects of type <code>ContainerSchemaNode</code>)\r
304      * @throws IllegalArgumentException\r
305      *             <ul>\r
306      *             <li>if the module equals null</li>\r
307      *             <li>if the name of module equals null</li>\r
308      *             <li>if the set of child nodes equals null</li>\r
309      *             </ul>\r
310      *\r
311      */\r
312     private def List<Type> allContainersToGenTypes(Module module) {\r
313         checkArgument(module !== null, "Module reference cannot be NULL.");\r
314 \r
315         checkArgument(module.name !== null, "Module name cannot be NULL.");\r
316 \r
317         if(module.childNodes === null) {\r
318             throw new IllegalArgumentException(\r
319                 "Reference to Set of Child Nodes in module " + module.name + " cannot be NULL.");\r
320         }\r
321 \r
322         val List<Type> generatedTypes = new ArrayList();\r
323         val it = new DataNodeIterator(module);\r
324         val List<ContainerSchemaNode> schemaContainers = it.allContainers();\r
325         val basePackageName = moduleNamespaceToPackageName(module);\r
326         for (container : schemaContainers) {\r
327             if(!container.isAddedByUses()) {\r
328                 generatedTypes.addAll(dataNodeContainerToGenType(basePackageName, container, module));\r
329             }\r
330         }\r
331         return generatedTypes;\r
332     }\r
333 \r
334     /**\r
335      * Converts all <b>lists</b> of the module to the list of <code>Type</code>\r
336      * objects.\r
337      *\r
338      * @param module\r
339      *            module from which is obtained DataNodeIterator to iterate over\r
340      *            all lists\r
341      * @return list of <code>Type</code> which are generated from lists (objects\r
342      *         of type <code>ListSchemaNode</code>)\r
343      * @throws IllegalArgumentException\r
344      *             <ul>\r
345      *             <li>if the module equals null</li>\r
346      *             <li>if the name of module equals null</li>\r
347      *             <li>if the set of child nodes equals null</li>\r
348      *             </ul>\r
349      *\r
350      */\r
351     private def List<Type> allListsToGenTypes(Module module) {\r
352         checkArgument(module !== null, "Module reference cannot be NULL.");\r
353         checkArgument(module.name !== null, "Module name cannot be NULL.");\r
354 \r
355         if(module.childNodes === null) {\r
356             throw new IllegalArgumentException(\r
357                 "Reference to Set of Child Nodes in module " + module.name + " cannot be NULL.");\r
358         }\r
359 \r
360         val List<Type> generatedTypes = new ArrayList();\r
361         val it = new DataNodeIterator(module);\r
362         val List<ListSchemaNode> schemaLists = it.allLists();\r
363         val basePackageName = moduleNamespaceToPackageName(module);\r
364         if(schemaLists !== null) {\r
365             for (list : schemaLists) {\r
366                 if(!list.isAddedByUses()) {\r
367                     generatedTypes.addAll(dataNodeContainerToGenType(basePackageName, list, module));\r
368                 }\r
369             }\r
370         }\r
371         return generatedTypes;\r
372     }\r
373 \r
374     /**\r
375      * Converts all <b>choices</b> of the module to the list of\r
376      * <code>Type</code> objects.\r
377      *\r
378      * @param module\r
379      *            module from which is obtained DataNodeIterator to iterate over\r
380      *            all choices\r
381      * @return list of <code>Type</code> which are generated from choices\r
382      *         (objects of type <code>ChoiceNode</code>)\r
383      * @throws IllegalArgumentException\r
384      *             <ul>\r
385      *             <li>if the module equals null</li>\r
386      *             <li>if the name of module equals null</li> *\r
387      *             </ul>\r
388      *\r
389      */\r
390     private def List<Type> allChoicesToGenTypes(Module module) {\r
391         checkArgument(module !== null, "Module reference cannot be NULL.");\r
392         checkArgument(module.name !== null, "Module name cannot be NULL.");\r
393 \r
394         val it = new DataNodeIterator(module);\r
395         val choiceNodes = it.allChoices();\r
396         val basePackageName = moduleNamespaceToPackageName(module);\r
397 \r
398         val List<Type> generatedTypes = new ArrayList();\r
399         for (choice : choiceNodes) {\r
400             if((choice !== null) && !choice.isAddedByUses()) {\r
401                 generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice, module));\r
402             }\r
403         }\r
404         return generatedTypes;\r
405     }\r
406 \r
407     /**\r
408      * Converts all <b>augmentation</b> of the module to the list\r
409      * <code>Type</code> objects.\r
410      *\r
411      * @param module\r
412      *            module from which is obtained list of all augmentation objects\r
413      *            to iterate over them\r
414      * @return list of <code>Type</code> which are generated from augments\r
415      *         (objects of type <code>AugmentationSchema</code>)\r
416      * @throws IllegalArgumentException\r
417      *             <ul>\r
418      *             <li>if the module equals null</li>\r
419      *             <li>if the name of module equals null</li>\r
420      *             <li>if the set of child nodes equals null</li>\r
421      *             </ul>\r
422      *\r
423      */\r
424     private def List<Type> allAugmentsToGenTypes(Module module) {\r
425         checkArgument(module !== null, "Module reference cannot be NULL.");\r
426         checkArgument(module.name !== null, "Module name cannot be NULL.");\r
427         if(module.childNodes === null) {\r
428             throw new IllegalArgumentException(\r
429                 "Reference to Set of Augmentation Definitions in module " + module.name + " cannot be NULL.");\r
430         }\r
431 \r
432         val List<Type> generatedTypes = new ArrayList();\r
433         val basePackageName = moduleNamespaceToPackageName(module);\r
434         val List<AugmentationSchema> augmentations = resolveAugmentations(module);\r
435         for (augment : augmentations) {\r
436             generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment, module, false));\r
437         }\r
438         return generatedTypes;\r
439     }\r
440 \r
441     /**\r
442      * Returns list of <code>AugmentationSchema</code> objects. The objects are\r
443      * sorted according to the length of their target path from the shortest to\r
444      * the longest.\r
445      *\r
446      * @param module\r
447      *            module from which is obtained list of all augmentation objects\r
448      * @return list of sorted <code>AugmentationSchema</code> objects obtained\r
449      *         from <code>module</code>\r
450      * @throws IllegalArgumentException\r
451      *             <ul>\r
452      *             <li>if the module equals null</li>\r
453      *             <li>if the set of augmentation equals null</li>\r
454      *             </ul>\r
455      *\r
456      */\r
457     private def List<AugmentationSchema> resolveAugmentations(Module module) {\r
458         checkArgument(module !== null, "Module reference cannot be NULL.");\r
459         checkState(module.augmentations !== null, "Augmentations Set cannot be NULL.");\r
460 \r
461         val Set<AugmentationSchema> augmentations = module.augmentations;\r
462         val List<AugmentationSchema> sortedAugmentations = new ArrayList(augmentations);\r
463         Collections.sort(sortedAugmentations,\r
464             [ augSchema1, augSchema2 |\r
465                 if(augSchema1.targetPath.path.size() > augSchema2.targetPath.path.size()) {\r
466                     return 1;\r
467                 } else if(augSchema1.targetPath.path.size() < augSchema2.targetPath.path.size()) {\r
468                     return -1;\r
469                 }\r
470                 return 0;\r
471             ]);\r
472         return sortedAugmentations;\r
473     }\r
474 \r
475     /**\r
476      * Converts whole <b>module</b> to <code>GeneratedType</code> object.\r
477      * Firstly is created the module builder object from which is vally\r
478      * obtained reference to <code>GeneratedType</code> object.\r
479      *\r
480      * @param module\r
481      *            module from which are obtained the module name, child nodes,\r
482      *            uses and is derived package name\r
483      * @return <code>GeneratedType</code> which is internal representation of\r
484      *         the module\r
485      * @throws IllegalArgumentException\r
486      *             if the module equals null\r
487      *\r
488      */\r
489     private def GeneratedType moduleToDataType(Module module) {\r
490         checkArgument(module !== null, "Module reference cannot be NULL.");\r
491 \r
492         val moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");\r
493         addImplementedInterfaceFromUses(module, moduleDataTypeBuilder);\r
494         moduleDataTypeBuilder.addImplementsType(DATA_ROOT);\r
495 \r
496         val basePackageName = moduleNamespaceToPackageName(module);\r
497         if(moduleDataTypeBuilder !== null) {\r
498             val Set<DataSchemaNode> dataNodes = module.childNodes;\r
499             resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes);\r
500         }\r
501         return moduleDataTypeBuilder.toInstance();\r
502     }\r
503 \r
504     /**\r
505      * Converts all <b>rpcs</b> inputs and outputs substatements of the module\r
506      * to the list of <code>Type</code> objects. In addition are to containers\r
507      * and lists which belong to input or output also part of returning list.\r
508      *\r
509      * @param module\r
510      *            module from which is obtained set of all rpc objects to\r
511      *            iterate over them\r
512      * @return list of <code>Type</code> which are generated from rpcs inputs,\r
513      *         outputs + container and lists which are part of inputs or outputs\r
514      * @throws IllegalArgumentException\r
515      *             <ul>\r
516      *             <li>if the module equals null</li>\r
517      *             <li>if the name of module equals null</li>\r
518      *             <li>if the set of child nodes equals null</li>\r
519      *             </ul>\r
520      *\r
521      */\r
522     private def List<Type> allRPCMethodsToGenType(Module module) {\r
523         checkArgument(module !== null, "Module reference cannot be NULL.");\r
524 \r
525         checkArgument(module.name !== null, "Module name cannot be NULL.");\r
526 \r
527         if(module.childNodes === null) {\r
528             throw new IllegalArgumentException(\r
529                 "Reference to Set of RPC Method Definitions in module " + module.name + " cannot be NULL.");\r
530         }\r
531 \r
532         val basePackageName = moduleNamespaceToPackageName(module);\r
533         val Set<RpcDefinition> rpcDefinitions = module.rpcs;\r
534 \r
535         if(rpcDefinitions.isEmpty()) {\r
536             return Collections.emptyList();\r
537         }\r
538 \r
539         val List<Type> genRPCTypes = new ArrayList();\r
540         val interfaceBuilder = moduleTypeBuilder(module, "Service");\r
541         interfaceBuilder.addImplementsType(Types.typeForClass(RpcService));\r
542         for (rpc : rpcDefinitions) {\r
543             if(rpc !== null) {\r
544 \r
545                 val rpcName = parseToClassName(rpc.QName.localName);\r
546                 val rpcMethodName = parseToValidParamName(rpcName);\r
547                 val method = interfaceBuilder.addMethod(rpcMethodName);\r
548 \r
549                 val rpcInOut = new ArrayList();\r
550 \r
551                 val input = rpc.input;\r
552                 val output = rpc.output;\r
553 \r
554                 if(input !== null) {\r
555                     rpcInOut.add(new DataNodeIterator(input));\r
556                     val inType = addRawInterfaceDefinition(basePackageName, input, rpcName);\r
557                     addImplementedInterfaceFromUses(input, inType);\r
558                     inType.addImplementsType(DATA_OBJECT);\r
559                     inType.addImplementsType(augmentable(inType));\r
560                     resolveDataSchemaNodes(basePackageName, inType, input.childNodes);\r
561                     val inTypeInstance = inType.toInstance();\r
562                     genRPCTypes.add(inTypeInstance);\r
563                     method.addParameter(inTypeInstance, "input");\r
564                 }\r
565 \r
566                 var Type outTypeInstance = VOID;\r
567                 if(output !== null) {\r
568                     rpcInOut.add(new DataNodeIterator(output));\r
569                     val outType = addRawInterfaceDefinition(basePackageName, output, rpcName);\r
570                     addImplementedInterfaceFromUses(output, outType);\r
571                     outType.addImplementsType(DATA_OBJECT);\r
572                     outType.addImplementsType(augmentable(outType));\r
573 \r
574                     resolveDataSchemaNodes(basePackageName, outType, output.childNodes);\r
575                     outTypeInstance = outType.toInstance();\r
576                     genRPCTypes.add(outTypeInstance);\r
577 \r
578                 }\r
579 \r
580                 val rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult), outTypeInstance);\r
581                 method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes));\r
582                 for (iter : rpcInOut) {\r
583                     val List<ContainerSchemaNode> nContainers = iter.allContainers();\r
584                     if((nContainers !== null) && !nContainers.isEmpty()) {\r
585                         for (container : nContainers) {\r
586                             if(!container.isAddedByUses()) {\r
587                                 genRPCTypes.addAll(dataNodeContainerToGenType(basePackageName, container, module));\r
588                             }\r
589                         }\r
590                     }\r
591                     val List<ListSchemaNode> nLists = iter.allLists();\r
592                     if((nLists !== null) && !nLists.isEmpty()) {\r
593                         for (list : nLists) {\r
594                             if(!list.isAddedByUses()) {\r
595                                 genRPCTypes.addAll(dataNodeContainerToGenType(basePackageName, list, module));\r
596                             }\r
597                         }\r
598                     }\r
599                     val List<ChoiceNode> nChoices = iter.allChoices();\r
600                     if((nChoices !== null) && !nChoices.isEmpty()) {\r
601                         for (choice : nChoices) {\r
602                             if(!choice.isAddedByUses()) {\r
603                                 genRPCTypes.addAll(choiceToGeneratedType(basePackageName, choice, module));\r
604                             }\r
605                         }\r
606                     }\r
607                 }\r
608             }\r
609         }\r
610         genRPCTypes.add(interfaceBuilder.toInstance());\r
611         return genRPCTypes;\r
612     }\r
613 \r
614     /**\r
615      * Converts all <b>notifications</b> of the module to the list of\r
616      * <code>Type</code> objects. In addition are to this list added containers\r
617      * and lists which are part of this notification.\r
618      *\r
619      * @param module\r
620      *            module from which is obtained set of all notification objects\r
621      *            to iterate over them\r
622      * @return list of <code>Type</code> which are generated from notification\r
623      *         (object of type <code>NotificationDefinition</code>\r
624      * @throws IllegalArgumentException\r
625      *             <ul>\r
626      *             <li>if the module equals null</li>\r
627      *             <li>if the name of module equals null</li>\r
628      *             <li>if the set of child nodes equals null</li>\r
629      *             </ul>\r
630      *\r
631      */\r
632     private def List<Type> allNotificationsToGenType(Module module) {\r
633         checkArgument(module !== null, "Module reference cannot be NULL.");\r
634 \r
635         checkArgument(module.name !== null, "Module name cannot be NULL.");\r
636 \r
637         if(module.childNodes === null) {\r
638             throw new IllegalArgumentException(\r
639                 "Reference to Set of Notification Definitions in module " + module.name + " cannot be NULL.");\r
640         }\r
641         val notifications = module.notifications;\r
642         if(notifications.isEmpty()) return Collections.emptyList();\r
643 \r
644         val listenerInterface = moduleTypeBuilder(module, "Listener");\r
645         listenerInterface.addImplementsType(BindingTypes.NOTIFICATION_LISTENER);\r
646 \r
647         val basePackageName = moduleNamespaceToPackageName(module);\r
648         val List<Type> generatedTypes = new ArrayList();\r
649 \r
650         \r
651 \r
652         for (notification : notifications) {\r
653             if(notification !== null) {\r
654                 generatedTypes.addAll(processUsesAugments(notification, module));\r
655 \r
656                 val iter = new DataNodeIterator(notification);\r
657 \r
658                 // Containers\r
659                 for (node : iter.allContainers()) {\r
660                     if(!node.isAddedByUses()) {\r
661                         generatedTypes.addAll(dataNodeContainerToGenType(basePackageName, node, module));\r
662                     }\r
663                 }\r
664 \r
665                 // Lists\r
666                 for (node : iter.allLists()) {\r
667                     if(!node.isAddedByUses()) {\r
668                         generatedTypes.addAll(dataNodeContainerToGenType(basePackageName, node, module));\r
669                     }\r
670                 }\r
671                 val notificationInterface = addDefaultInterfaceDefinition(basePackageName, notification);\r
672                 notificationInterface.addImplementsType(NOTIFICATION);\r
673 \r
674                 // Notification object\r
675                 resolveDataSchemaNodes(basePackageName, notificationInterface, notification.childNodes);\r
676 \r
677                 listenerInterface.addMethod("on" + notificationInterface.name) //\r
678                 .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification").\r
679                     setReturnType(Types.VOID);\r
680 \r
681                 generatedTypes.add(notificationInterface.toInstance());\r
682             }\r
683         }\r
684         generatedTypes.add(listenerInterface.toInstance());\r
685         return generatedTypes;\r
686     }\r
687 \r
688     /**\r
689      * Converts all <b>identities</b> of the module to the list of\r
690      * <code>Type</code> objects.\r
691      *\r
692      * @param module\r
693      *            module from which is obtained set of all identity objects to\r
694      *            iterate over them\r
695      * @param context\r
696      *            schema context only used as input parameter for method\r
697      *            {@link identityToGenType}\r
698      * @return list of <code>Type</code> which are generated from identities\r
699      *         (object of type <code>IdentitySchemaNode</code>\r
700      *\r
701      */\r
702     private def List<Type> allIdentitiesToGenTypes(Module module, SchemaContext context) {\r
703         val List<Type> genTypes = new ArrayList();\r
704 \r
705         val Set<IdentitySchemaNode> schemaIdentities = module.identities;\r
706 \r
707         val basePackageName = moduleNamespaceToPackageName(module);\r
708 \r
709         if(schemaIdentities !== null && !schemaIdentities.isEmpty()) {\r
710             for (identity : schemaIdentities) {\r
711                 genTypes.add(identityToGenType(basePackageName, identity, context));\r
712             }\r
713         }\r
714         return genTypes;\r
715     }\r
716 \r
717     /**\r
718      * Converts the <b>identity</b> object to GeneratedType. Firstly it is\r
719      * created transport object builder. If identity contains base identity then\r
720      * reference to base identity is added to superior identity as its extend.\r
721      * If identity doesn't contain base identity then only reference to abstract\r
722      * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity\r
723      * BaseIdentity} is added\r
724      *\r
725      * @param basePackageName\r
726      *            string contains the module package name\r
727      * @param identity\r
728      *            IdentitySchemaNode which contains data about identity\r
729      * @param context\r
730      *            SchemaContext which is used to get package and name\r
731      *            information about base of identity\r
732      *\r
733      * @return GeneratedType which is generated from identity (object of type\r
734      *         <code>IdentitySchemaNode</code>\r
735      *\r
736      */\r
737     private def GeneratedType identityToGenType(String basePackageName, IdentitySchemaNode identity,\r
738         SchemaContext context) {\r
739         if(identity === null) {\r
740             return null;\r
741         }\r
742 \r
743         val packageName = packageNameForGeneratedType(basePackageName, identity.path);\r
744         val genTypeName = parseToClassName(identity.QName.localName);\r
745         val newType = new GeneratedTOBuilderImpl(packageName, genTypeName);\r
746 \r
747         val baseIdentity = identity.baseIdentity;\r
748         if(baseIdentity !== null) {\r
749             val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);\r
750 \r
751             val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);\r
752             val returnTypeName = parseToClassName(baseIdentity.QName.localName);\r
753 \r
754             val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();\r
755             newType.setExtendsType(gto);\r
756         } else {\r
757             newType.setExtendsType(Types.baseIdentityTO);\r
758         }\r
759         newType.setAbstract(true);\r
760         return newType.toInstance();\r
761     }\r
762 \r
763     /**\r
764      * Converts all <b>groupings</b> of the module to the list of\r
765      * <code>Type</code> objects. Firstly are groupings sorted according mutual\r
766      * dependencies. At least dependend (indepedent) groupings are in the list\r
767      * saved at first positions. For every grouping the record is added to map\r
768      * {@link BindingGeneratorImpl#allGroupings allGroupings}\r
769      *\r
770      * @param module\r
771      *            module from which is obtained set of all grouping objects to\r
772      *            iterate over them\r
773      * @return list of <code>Type</code> which are generated from groupings\r
774      *         (object of type <code>GroupingDefinition</code>)\r
775      *\r
776      */\r
777     private def List<Type> allGroupingsToGenTypes(Module module) {\r
778         checkArgument(module !== null, "Module parameter can not be null");\r
779         val List<Type> genTypes = new ArrayList();\r
780         val basePackageName = moduleNamespaceToPackageName(module);\r
781         val it = new DataNodeIterator(module);\r
782         val List<GroupingDefinition> groupings = it.allGroupings();\r
783         val List<GroupingDefinition> groupingsSortedByDependencies = new GroupingDefinitionDependencySort().sort(\r
784             groupings);\r
785 \r
786         for (grouping : groupingsSortedByDependencies) {\r
787             val genType = groupingToGenType(basePackageName, grouping, module);\r
788             genTypes.add(genType);\r
789             genTypes.addAll(processUsesAugments(grouping, module));\r
790             val schemaPath = grouping.path;\r
791             allGroupings.put(schemaPath, genType);\r
792         }\r
793         return genTypes;\r
794     }\r
795 \r
796     /**\r
797      * Converts individual grouping to GeneratedType. Firstly generated type\r
798      * builder is created and every child node of grouping is resolved to the\r
799      * method.\r
800      *\r
801      * @param basePackageName\r
802      *            string contains the module package name\r
803      * @param grouping\r
804      *            GroupingDefinition which contains data about grouping\r
805      * @return GeneratedType which is generated from grouping (object of type\r
806      *         <code>GroupingDefinition</code>)\r
807      */\r
808     private def GeneratedType groupingToGenType(String basePackageName, GroupingDefinition grouping, Module module) {\r
809         if(grouping === null) {\r
810             return null;\r
811         }\r
812 \r
813         val packageName = packageNameForGeneratedType(basePackageName, grouping.path);\r
814         val Set<DataSchemaNode> schemaNodes = grouping.childNodes;\r
815         val typeBuilder = addDefaultInterfaceDefinition(packageName, grouping);\r
816 \r
817         resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);\r
818 \r
819         return typeBuilder.toInstance();\r
820     }\r
821 \r
822     /**\r
823      * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base\r
824      * type of <code>typeDefinition</code> is of the type ExtendedType then this\r
825      * method is recursivelly called with this base type.\r
826      *\r
827      * @param typeDefinition\r
828      *            TypeDefinition in which should be EnumTypeDefinition found as\r
829      *            base type\r
830      * @return EnumTypeDefinition if it is found inside\r
831      *         <code>typeDefinition</code> or <code>null</code> in other case\r
832      */\r
833     private def EnumTypeDefinition enumTypeDefFromExtendedType(TypeDefinition<?> typeDefinition) {\r
834         if(typeDefinition !== null) {\r
835             if(typeDefinition.baseType instanceof EnumTypeDefinition) {\r
836                 return typeDefinition.baseType as EnumTypeDefinition;\r
837             } else if(typeDefinition.baseType instanceof ExtendedType) {\r
838                 return enumTypeDefFromExtendedType(typeDefinition.baseType);\r
839             }\r
840         }\r
841         return null;\r
842     }\r
843 \r
844     /**\r
845      * Adds enumeration builder created from <code>enumTypeDef</code> to\r
846      * <code>typeBuilder</code>.\r
847      *\r
848      * Each <code>enumTypeDef</code> item is added to builder with its name and\r
849      * value.\r
850      *\r
851      * @param enumTypeDef\r
852      *            EnumTypeDefinition contains enum data\r
853      * @param enumName\r
854      *            string contains name which will be assigned to enumeration\r
855      *            builder\r
856      * @param typeBuilder\r
857      *            GeneratedTypeBuilder to which will be enum builder assigned\r
858      * @return enumeration builder which contais data from\r
859      *         <code>enumTypeDef</code>\r
860      */\r
861     private def EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, String enumName,\r
862         GeneratedTypeBuilder typeBuilder) {\r
863         if((enumTypeDef !== null) && (typeBuilder !== null) && (enumTypeDef.QName !== null) &&\r
864             (enumTypeDef.QName.localName !== null)) {\r
865 \r
866             val enumerationName = parseToClassName(enumName);\r
867             val enumBuilder = typeBuilder.addEnumeration(enumerationName);\r
868             enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);\r
869 \r
870             return enumBuilder;\r
871         }\r
872         return null;\r
873     }\r
874 \r
875     /**\r
876      * Generates type builder for <code>module</code>.\r
877      *\r
878      * @param module\r
879      *            Module which is source of package name for generated type\r
880      *            builder\r
881      * @param postfix\r
882      *            string which is added to the module class name representation\r
883      *            as suffix\r
884      * @return instance of GeneratedTypeBuilder which represents\r
885      *         <code>module</code>.\r
886      * @throws IllegalArgumentException\r
887      *             if <code>module</code> equals null\r
888      */\r
889     private def GeneratedTypeBuilder moduleTypeBuilder(Module module, String postfix) {\r
890         checkArgument(module !== null, "Module reference cannot be NULL.");\r
891         val packageName = moduleNamespaceToPackageName(module);\r
892         val moduleName = parseToClassName(module.name) + postfix;\r
893 \r
894         return new GeneratedTypeBuilderImpl(packageName, moduleName);\r
895     }\r
896 \r
897     /**\r
898      * Converts <code>augSchema</code> to list of <code>Type</code> which\r
899      * contains generated type for augmentation. In addition there are also\r
900      * generated types for all containers, list and choices which are child of\r
901      * <code>augSchema</code> node or a generated types for cases are added if\r
902      * augmented node is choice.\r
903      *\r
904      * @param augmentPackageName\r
905      *            string with the name of the package to which the augmentation\r
906      *            belongs\r
907      * @param augSchema\r
908      *            AugmentationSchema which is contains data about agumentation\r
909      *            (target path, childs...)\r
910      * @return list of <code>Type</code> objects which contains generated type\r
911      *         for augmentation and for container, list and choice child nodes\r
912      * @throws IllegalArgumentException\r
913      *             <ul>\r
914      *             <li>if <code>augmentPackageName</code> equals null</li>\r
915      *             <li>if <code>augSchema</code> equals null</li>\r
916      *             <li>if target path of <code>augSchema</code> equals null</li>\r
917      *             </ul>\r
918      */\r
919     private def List<Type> augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module, boolean addedByUses) {\r
920         checkArgument(augmentPackageName !== null, "Package Name cannot be NULL.");\r
921         checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL.");\r
922         checkState(augSchema.targetPath !== null,\r
923             "Augmentation Schema does not contain Target Path (Target Path is NULL).");\r
924         val List<Type> genTypes = new ArrayList();\r
925         genTypes.addAll(processUsesAugments(augSchema, module));\r
926 \r
927         // EVERY augmented interface will extends Augmentation<T> interface\r
928         // and DataObject interface!!!\r
929         val targetPath = augSchema.targetPath;\r
930         var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);\r
931         if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) {\r
932                         targetSchemaNode = findOriginalTargetFromGrouping(targetPath, module, targetSchemaNode as DataSchemaNode);\r
933         }\r
934 \r
935         if(targetSchemaNode !== null) {\r
936             var targetType = yangToJavaMapping.get(targetSchemaNode.path);\r
937             if(targetType == null) {\r
938 \r
939                 // FIXME: augmentation should be added as last, all types should already be generated\r
940                 // and have assigned Java Types,\r
941                 val targetModule = findParentModule(schemaContext, targetSchemaNode);\r
942                 val targetBasePackage = moduleNamespaceToPackageName(targetModule);\r
943                 val typePackage = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath());\r
944                 val targetSchemaNodeName = targetSchemaNode.getQName().getLocalName();\r
945                 val typeName = parseToClassName(targetSchemaNodeName);\r
946                 targetType = new ReferencedTypeImpl(typePackage, typeName);\r
947             }\r
948             val augChildNodes = augSchema.childNodes;\r
949 \r
950             if(!(targetSchemaNode instanceof ChoiceNode)) {\r
951                 var packageName = augmentPackageName;\r
952                 if (addedByUses) {\r
953                     packageName = packageNameForGeneratedType(augmentPackageName, augSchema.targetPath);\r
954                 }\r
955                 val augTypeBuilder = addRawAugmentGenTypeDefinition(packageName, augmentPackageName, targetType, augSchema);\r
956                 val augType = augTypeBuilder.toInstance();\r
957                 genTypes.add(augType);\r
958             } else {\r
959                 genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, targetType, augChildNodes, targetSchemaNode as ChoiceNode));\r
960             }\r
961             genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes, module));\r
962         }\r
963                 \r
964         return genTypes;\r
965     }\r
966 \r
967     private def DataSchemaNode findOriginalTargetFromGrouping(SchemaPath targetPath, Module module, DataSchemaNode targetSchemaNode) {\r
968         val path = new ArrayList<QName>(targetPath.getPath());\r
969         path.remove(path.size()-1);\r
970         var DataNodeContainer parent = null;\r
971 \r
972         if (path.isEmpty()) {\r
973             parent = module;\r
974         } else {\r
975             parent = findNodeInSchemaContext(schemaContext, path) as DataNodeContainer;\r
976         }\r
977 \r
978         val Set<UsesNode> usesNodes = parent.getUses();\r
979         if (usesNodes == null || usesNodes.isEmpty()) {\r
980             return targetSchemaNode;\r
981         }\r
982         val Set<SchemaPath> groupingPaths = new HashSet<SchemaPath>();\r
983         for (uses : usesNodes) {\r
984             groupingPaths.add(uses.getGroupingPath());\r
985         }\r
986         val Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();\r
987         for (gp : groupingPaths) {\r
988             groupings.add(findGrouping(schemaContext, module, gp.getPath()));\r
989         }\r
990 \r
991         var DataSchemaNode result = findNodeInGroupings(groupings, targetSchemaNode.getQName().localName);\r
992         return result;\r
993     }\r
994 \r
995     private def DataSchemaNode findNodeInGroupings(Set<GroupingDefinition> groupings, String name) {\r
996         for (gr : groupings) {\r
997             var DataSchemaNode node = gr.getDataChildByName(name);\r
998             if (node != null) {\r
999                 return node;\r
1000             }\r
1001         }\r
1002         return null;\r
1003     }\r
1004 \r
1005     /**\r
1006      * Returns a generated type builder for an augmentation.\r
1007      *\r
1008      * The name of the type builder is equal to the name of augmented node with\r
1009      * serial number as suffix.\r
1010      *\r
1011      * @param augmentPackageName\r
1012      *            string with contains the package name to which the augment\r
1013      *            belongs\r
1014      * @param targetPackageName\r
1015      *            string with the package name to which the augmented node\r
1016      *            belongs\r
1017      * @param targetSchemaNodeName\r
1018      *            string with the name of the augmented node\r
1019      * @param augSchema\r
1020      *            augmentation schema which contains data about the child nodes\r
1021      *            and uses of augment\r
1022      * @return generated type builder for augment\r
1023      */\r
1024     private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition(String augmentPackageName, String basePackageName,
1025                 Type targetTypeRef, AugmentationSchema augSchema) {
1026                 var Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
1027                 if (augmentBuilders === null) {
1028                         augmentBuilders = new HashMap();
1029                         genTypeBuilders.put(augmentPackageName, augmentBuilders);
1030                 }
1031                 val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes);
1032
1033                 val augTypeName = if (augIdentifier !== null) {
1034                                 parseToClassName(augIdentifier)
1035                         } else {
1036                                 augGenTypeName(augmentBuilders, targetTypeRef.name);
1037                         }
1038
1039                 val augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);
1040
1041                 augTypeBuilder.addImplementsType(DATA_OBJECT);
1042                 augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));
1043                 addImplementedInterfaceFromUses(augSchema, augTypeBuilder);
1044
1045                 augSchemaNodeToMethods(basePackageName, augTypeBuilder, augSchema.childNodes);
1046                 augmentBuilders.put(augTypeName, augTypeBuilder);
1047                 return augTypeBuilder;
1048         }\r
1049 \r
1050     /**\r
1051      *\r
1052      * @param unknownSchemaNodes\r
1053      * @return nodeParameter of UnknownSchemaNode\r
1054      */\r
1055     private def String getAugmentIdentifier(List<UnknownSchemaNode> unknownSchemaNodes) {\r
1056         for (unknownSchemaNode : unknownSchemaNodes) {\r
1057             val nodeType = unknownSchemaNode.nodeType;\r
1058             if(AUGMENT_IDENTIFIER_NAME.equals(nodeType.localName) &&\r
1059                 YANG_EXT_NAMESPACE.equals(nodeType.namespace.toString())) {\r
1060                 return unknownSchemaNode.nodeParameter;\r
1061             }\r
1062         }\r
1063         return null;\r
1064     }\r
1065 \r
1066     /**\r
1067      * Convert a container, list and choice subnodes (and recursivelly their\r
1068      * subnodes) of augment to generated types\r
1069      *\r
1070      * @param augBasePackageName\r
1071      *            string with the augment package name\r
1072      * @param augChildNodes\r
1073      *            set of data schema nodes which represents child nodes of the\r
1074      *            augment\r
1075      *\r
1076      * @return list of <code>Type</code> which represents container, list and\r
1077      *         choice subnodes of augment\r
1078      */\r
1079     private def List<Type> augmentationBodyToGenTypes(String augBasePackageName, Set<DataSchemaNode> augChildNodes, Module module) {\r
1080         val List<Type> genTypes = new ArrayList();\r
1081         val List<DataNodeIterator> augSchemaIts = new ArrayList();\r
1082         for (childNode : augChildNodes) {\r
1083             if(childNode instanceof DataNodeContainer) {\r
1084                 augSchemaIts.add(new DataNodeIterator(childNode as DataNodeContainer));\r
1085 \r
1086                 if(childNode instanceof ContainerSchemaNode) {\r
1087                     genTypes.addAll(dataNodeContainerToGenType(augBasePackageName, childNode as ContainerSchemaNode, module));\r
1088                 } else if(childNode instanceof ListSchemaNode) {\r
1089                     genTypes.addAll(dataNodeContainerToGenType(augBasePackageName, childNode as ListSchemaNode, module));\r
1090                 }\r
1091             } else if(childNode instanceof ChoiceNode) {\r
1092                 val choice = childNode as ChoiceNode;\r
1093                 for (caseNode : choice.cases) {\r
1094                     augSchemaIts.add(new DataNodeIterator(caseNode));\r
1095                 }\r
1096                 genTypes.addAll(choiceToGeneratedType(augBasePackageName, childNode as ChoiceNode, module));\r
1097             }\r
1098         }\r
1099 \r
1100         for (it : augSchemaIts) {\r
1101             val List<ContainerSchemaNode> augContainers = it.allContainers();\r
1102             val List<ListSchemaNode> augLists = it.allLists();\r
1103             val List<ChoiceNode> augChoices = it.allChoices();\r
1104 \r
1105             if(augContainers !== null) {\r
1106                 for (container : augContainers) {\r
1107                     genTypes.addAll(dataNodeContainerToGenType(augBasePackageName, container, module));\r
1108                 }\r
1109             }\r
1110             if(augLists !== null) {\r
1111                 for (list : augLists) {\r
1112                     genTypes.addAll(dataNodeContainerToGenType(augBasePackageName, list, module));\r
1113                 }\r
1114             }\r
1115             if(augChoices !== null) {\r
1116                 for (choice : augChoices) {\r
1117                     genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice, module));\r
1118                 }\r
1119             }\r
1120         }\r
1121         return genTypes;\r
1122     }\r
1123 \r
1124     /**\r
1125      * Returns first unique name for the augment generated type builder. The\r
1126      * generated type builder name for augment consists from name of augmented\r
1127      * node and serial number of its augmentation.\r
1128      *\r
1129      * @param builders\r
1130      *            map of builders which were created in the package to which the\r
1131      *            augmentation belongs\r
1132      * @param genTypeName\r
1133      *            string with name of augmented node\r
1134      * @return string with unique name for augmentation builder\r
1135      */\r
1136     private def String augGenTypeName(Map<String, GeneratedTypeBuilder> builders, String genTypeName) {\r
1137         var index = 1;\r
1138         while((builders !== null) && builders.containsKey(genTypeName + index)) {\r
1139             index = index + 1;\r
1140         }\r
1141         return genTypeName + index;\r
1142     }\r
1143 \r
1144     /**\r
1145      * Adds the methods to <code>typeBuilder</code> which represent subnodes of\r
1146      * node for which <code>typeBuilder</code> was created.\r
1147      *\r
1148      * The subnodes aren't mapped to the methods if they are part of grouping or\r
1149      * augment (in this case are already part of them).\r
1150      *\r
1151      * @param basePackageName\r
1152      *            string contains the module package name\r
1153      * @param typeBuilder\r
1154      *            generated type builder which represents any node. The subnodes\r
1155      *            of this node are added to the <code>typeBuilder</code> as\r
1156      *            methods. The subnode can be of type leaf, leaf-list, list,\r
1157      *            container, choice.\r
1158      * @param schemaNodes\r
1159      *            set of data schema nodes which are the children of the node\r
1160      *            for which <code>typeBuilder</code> was created\r
1161      * @return generated type builder which is the same builder as input\r
1162      *         parameter. The getter methods (representing child nodes) could be\r
1163      *         added to it.\r
1164      */\r
1165     private def GeneratedTypeBuilder resolveDataSchemaNodes(String basePackageName, GeneratedTypeBuilder typeBuilder,\r
1166         Set<DataSchemaNode> schemaNodes) {\r
1167         if((schemaNodes !== null) && (typeBuilder !== null)) {\r
1168             for (schemaNode : schemaNodes) {\r
1169                 if(!schemaNode.isAugmenting() && !schemaNode.isAddedByUses()) {\r
1170                     addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);\r
1171                 }\r
1172 \r
1173             }\r
1174         }\r
1175         return typeBuilder;\r
1176     }\r
1177         \r
1178         private def GeneratedTypeBuilder resolveDataSchemaNodesAugmented(String basePackageName, GeneratedTypeBuilder typeBuilder,\r
1179                 Set<DataSchemaNode> schemaNodes) {\r
1180                 if ((schemaNodes !== null) && (typeBuilder !== null)) {\r
1181                         for (schemaNode : schemaNodes) {\r
1182                                 if (!schemaNode.isAddedByUses()) {\r
1183                                         addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);\r
1184                                 }\r
1185                         }\r
1186                 }\r
1187                 return typeBuilder;\r
1188         }\r
1189 \r
1190     /**\r
1191      * Adds the methods to <code>typeBuilder</code> what represents subnodes of\r
1192      * node for which <code>typeBuilder</code> was created.\r
1193      *\r
1194      * @param basePackageName\r
1195      *            string contains the module package name\r
1196      * @param typeBuilder\r
1197      *            generated type builder which represents any node. The subnodes\r
1198      *            of this node are added to the <code>typeBuilder</code> as\r
1199      *            methods. The subnode can be of type leaf, leaf-list, list,\r
1200      *            container, choice.\r
1201      * @param schemaNodes\r
1202      *            set of data schema nodes which are the children of the node\r
1203      *            for which <code>typeBuilder</code> was created\r
1204      * @return generated type builder which is the same object as the input\r
1205      *         parameter <code>typeBuilder</code>. The getter method could be\r
1206      *         added to it.\r
1207      */\r
1208     private def GeneratedTypeBuilder augSchemaNodeToMethods(String basePackageName, GeneratedTypeBuilder typeBuilder,\r
1209         Set<DataSchemaNode> schemaNodes) {\r
1210         if((schemaNodes !== null) && (typeBuilder !== null)) {\r
1211             for (schemaNode : schemaNodes) {\r
1212                             if (!schemaNode.isAugmenting()) {\r
1213                                     addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);\r
1214                                 }\r
1215                         }\r
1216                 }\r
1217                 return typeBuilder;\r
1218         }\r
1219 \r
1220     /**\r
1221      * Adds to <code>typeBuilder</code> a method which is derived from\r
1222      * <code>schemaNode</code>.\r
1223      *\r
1224      * @param basePackageName\r
1225      *            string with the module package name\r
1226      * @param schemaNode\r
1227      *            data schema node which is added to <code>typeBuilder</code> as\r
1228      *            a method\r
1229      * @param typeBuilder\r
1230      *            generated type builder to which is <code>schemaNode</code>\r
1231      *            added as a method.\r
1232      */\r
1233     private def void addSchemaNodeToBuilderAsMethod(String basePackageName, DataSchemaNode node,\r
1234         GeneratedTypeBuilder typeBuilder) {\r
1235         if(node !== null && typeBuilder !== null) {\r
1236             switch (node) {\r
1237                 case node instanceof LeafSchemaNode:\r
1238                     resolveLeafSchemaNodeAsMethod(typeBuilder, node as LeafSchemaNode)\r
1239                 case node instanceof LeafListSchemaNode:\r
1240                     resolveLeafListSchemaNode(typeBuilder, node as LeafListSchemaNode)\r
1241                 case node instanceof ContainerSchemaNode:\r
1242                     resolveContainerSchemaNode(basePackageName, typeBuilder, node as ContainerSchemaNode)\r
1243                 case node instanceof ListSchemaNode:\r
1244                     resolveListSchemaNode(basePackageName, typeBuilder, node as ListSchemaNode)\r
1245                 case node instanceof ChoiceNode:\r
1246                     resolveChoiceSchemaNode(basePackageName, typeBuilder, node as ChoiceNode)\r
1247             }\r
1248         }\r
1249     }\r
1250 \r
1251     /**\r
1252      * Creates a getter method for a choice node.\r
1253      *\r
1254      * Firstly generated type builder for choice is created or found in\r
1255      * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name\r
1256      * in the builder is created as concatenation of module package name and\r
1257      * names of all parent nodes. In the end the getter method for choice is\r
1258      * added to <code>typeBuilder</code> and return type is set to choice\r
1259      * builder.\r
1260      *\r
1261      * @param basePackageName\r
1262      *            string with the module package name\r
1263      * @param typeBuilder\r
1264      *            generated type builder to which is <code>choiceNode</code>\r
1265      *            added as getter method\r
1266      * @param choiceNode\r
1267      *            choice node which is mapped as a getter method\r
1268      * @throws IllegalArgumentException\r
1269      *             <ul>\r
1270      *             <li>if <code>basePackageName</code> equals null</li>\r
1271      *             <li>if <code>typeBuilder</code> equals null</li>\r
1272      *             <li>if <code>choiceNode</code> equals null</li>\r
1273      *             </ul>\r
1274      *\r
1275      */\r
1276     private def void resolveChoiceSchemaNode(String basePackageName, GeneratedTypeBuilder typeBuilder,\r
1277         ChoiceNode choiceNode) {\r
1278         checkArgument(basePackageName !== null, "Base Package Name cannot be NULL.");\r
1279         checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL.");\r
1280         checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL.");\r
1281 \r
1282         val choiceName = choiceNode.QName.localName;\r
1283         if(choiceName !== null && !choiceNode.isAddedByUses()) {\r
1284             val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path);\r
1285             val choiceType = addDefaultInterfaceDefinition(packageName, choiceNode);\r
1286             constructGetter(typeBuilder, choiceName, choiceNode.description, choiceType);\r
1287         }\r
1288     }\r
1289 \r
1290     /**\r
1291      * Converts <code>choiceNode</code> to the list of generated types for\r
1292      * choice and its cases.\r
1293      *\r
1294      * The package names for choice and for its cases are created as\r
1295      * concatenation of the module package (<code>basePackageName</code>) and\r
1296      * names of all parents node.\r
1297      *\r
1298      * @param basePackageName\r
1299      *            string with the module package name\r
1300      * @param choiceNode\r
1301      *            choice node which is mapped to generated type. Also child\r
1302      *            nodes - cases are mapped to generated types.\r
1303      * @return list of generated types which contains generated type for choice\r
1304      *         and generated types for all cases which aren't added do choice\r
1305      *         through <i>uses</i>.\r
1306      * @throws IllegalArgumentException\r
1307      *             <ul>\r
1308      *             <li>if <code>basePackageName</code> equals null</li>\r
1309      *             <li>if <code>choiceNode</code> equals null</li>\r
1310      *             </ul>\r
1311      *\r
1312      */\r
1313     private def List<Type> choiceToGeneratedType(String basePackageName, ChoiceNode choiceNode, Module module) {\r
1314         checkArgument(basePackageName !== null, "Base Package Name cannot be NULL.");\r
1315         checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL.");\r
1316 \r
1317         val List<Type> generatedTypes = new ArrayList();\r
1318         val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path);\r
1319         val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);\r
1320 \r
1321         choiceTypeBuilder.addImplementsType(DataContainer.typeForClass);\r
1322         val choiceType = choiceTypeBuilder.toInstance();\r
1323 \r
1324         generatedTypes.add(choiceType);\r
1325         val Set<ChoiceCaseNode> caseNodes = choiceNode.cases;\r
1326         if((caseNodes !== null) && !caseNodes.isEmpty()) {\r
1327             generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes, module));\r
1328         }\r
1329         return generatedTypes;\r
1330     }\r
1331 \r
1332     /**\r
1333      * Converts <code>caseNodes</code> set to list of corresponding generated\r
1334      * types.\r
1335      *\r
1336      * For every <i>case</i> which isn't added through augment or <i>uses</i> is\r
1337      * created generated type builder. The package names for the builder is\r
1338      * created as concatenation of the module package (\r
1339      * <code>basePackageName</code>) and names of all parents nodes of the\r
1340      * concrete <i>case</i>. There is also relation "<i>implements type</i>"\r
1341      * between every case builder and <i>choice</i> type\r
1342      *\r
1343      * @param basePackageName\r
1344      *            string with the module package name\r
1345      * @param refChoiceType\r
1346      *            type which represents superior <i>case</i>\r
1347      * @param caseNodes\r
1348      *            set of choice case nodes which are mapped to generated types\r
1349      * @return list of generated types for <code>caseNodes</code>.\r
1350      * @throws IllegalArgumentException\r
1351      *             <ul>\r
1352      *             <li>if <code>basePackageName</code> equals null</li>\r
1353      *             <li>if <code>refChoiceType</code> equals null</li>\r
1354      *             <li>if <code>caseNodes</code> equals null</li>\r
1355      *             </ul>\r
1356      *             *\r
1357      */\r
1358     private def List<Type> generateTypesFromChoiceCases(String basePackageName, Type refChoiceType,\r
1359         Set<ChoiceCaseNode> caseNodes, Module module) {\r
1360         checkArgument(basePackageName !== null, "Base Package Name cannot be NULL.");\r
1361         checkArgument(refChoiceType !== null, "Referenced Choice Type cannot be NULL.");\r
1362         checkArgument(caseNodes !== null, "Set of Choice Case Nodes cannot be NULL.");\r
1363 \r
1364         val List<Type> generatedTypes = new ArrayList();\r
1365         for (caseNode : caseNodes) {\r
1366             if(caseNode !== null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) {\r
1367                 val packageName = packageNameForGeneratedType(basePackageName, caseNode.path);\r
1368                 val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);\r
1369                 caseTypeBuilder.addImplementsType(refChoiceType);\r
1370 \r
1371                 val Set<DataSchemaNode> childNodes = caseNode.childNodes;\r
1372                 if(childNodes !== null) {\r
1373                     resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);\r
1374                 }\r
1375                 generatedTypes.add(caseTypeBuilder.toInstance());\r
1376             }\r
1377             \r
1378             generatedTypes.addAll(processUsesAugments(caseNode, module));\r
1379         }\r
1380 \r
1381         return generatedTypes;\r
1382     }\r
1383 \r
1384     /**\r
1385      * Generates list of generated types for all the cases of a choice which are\r
1386      * added to the choice through the augment.\r
1387      *\r
1388      *\r
1389      * @param basePackageName\r
1390      *            string contains name of package to which augment belongs. If\r
1391      *            an augmented choice is from an other package (pcg1) than an\r
1392      *            augmenting choice (pcg2) then case's of the augmenting choice\r
1393      *            will belong to pcg2.\r
1394      * @param refChoiceType\r
1395      *            Type which represents the choice to which case belongs. Every\r
1396      *            case has to contain its choice in extend part.\r
1397      * @param caseNodes\r
1398      *            set of choice case nodes for which is checked if are/aren't\r
1399      *            added to choice through augmentation\r
1400      * @return list of generated types which represents augmented cases of\r
1401      *         choice <code>refChoiceType</code>\r
1402      * @throws IllegalArgumentException\r
1403      *             <ul>\r
1404      *             <li>if <code>basePackageName</code> equals null</li>\r
1405      *             <li>if <code>refChoiceType</code> equals null</li>\r
1406      *             <li>if <code>caseNodes</code> equals null</li>\r
1407      *             </ul>\r
1408      */\r
1409     private def List<GeneratedType> generateTypesFromAugmentedChoiceCases(String basePackageName, Type refChoiceType,\r
1410         Set<DataSchemaNode> caseNodes, ChoiceNode targetNode) {\r
1411         checkArgument(basePackageName !== null, "Base Package Name cannot be NULL.");\r
1412         checkArgument(refChoiceType !== null, "Referenced Choice Type cannot be NULL.");\r
1413         checkArgument(caseNodes !== null, "Set of Choice Case Nodes cannot be NULL.");\r
1414 \r
1415         val List<GeneratedType> generatedTypes = new ArrayList();\r
1416         for (caseNode : caseNodes) {\r
1417                 if(caseNode !== null) {\r
1418                 val packageName = packageNameForGeneratedType(basePackageName, caseNode.path);\r
1419                 val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);\r
1420                 caseTypeBuilder.addImplementsType(refChoiceType);\r
1421 \r
1422                 if (caseNode instanceof DataNodeContainer) {\r
1423                         val DataNodeContainer dataNodeCase = caseNode as DataNodeContainer;\r
1424                         val Set<DataSchemaNode> childNodes = dataNodeCase.childNodes;\r
1425                     if(childNodes !== null) {\r
1426                                             resolveDataSchemaNodesAugmented(basePackageName, caseTypeBuilder, childNodes);\r
1427                     }\r
1428                 } else {\r
1429                         val ChoiceCaseNode node = targetNode.getCaseNodeByName(caseNode.getQName().getLocalName());\r
1430                         val Set<DataSchemaNode> childNodes = node.childNodes;\r
1431                     if(childNodes !== null) {\r
1432                                             resolveDataSchemaNodesAugmented(basePackageName, caseTypeBuilder, childNodes);\r
1433                     }\r
1434                 }\r
1435                 \r
1436                 generatedTypes.add(caseTypeBuilder.toInstance());\r
1437             }\r
1438         }\r
1439 \r
1440         return generatedTypes;\r
1441     }\r
1442 \r
1443     /**\r
1444      * Converts <code>leaf</code> to the getter method which is added to\r
1445      * <code>typeBuilder</code>.\r
1446      *\r
1447      * @param typeBuilder\r
1448      *            generated type builder to which is added getter method as\r
1449      *            <code>leaf</code> mapping\r
1450      * @param leaf\r
1451      *            leaf schema node which is mapped as getter method which is\r
1452      *            added to <code>typeBuilder</code>\r
1453      * @return boolean value\r
1454      *         <ul>\r
1455      *         <li>false - if <code>leaf</code> or <code>typeBuilder</code> are\r
1456      *         null</li>\r
1457      *         <li>true - in other cases</li>\r
1458      *         </ul>\r
1459      */\r
1460     private def boolean resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) {\r
1461         if((leaf !== null) && (typeBuilder !== null)) {\r
1462             val leafName = leaf.QName.localName;\r
1463             var String leafDesc = leaf.description;\r
1464             if(leafDesc === null) {\r
1465                 leafDesc = "";\r
1466             }\r
1467 \r
1468             val parentModule = findParentModule(schemaContext, leaf);\r
1469             if(leafName !== null && !leaf.isAddedByUses()) {\r
1470                 val TypeDefinition<?> typeDef = leaf.type;\r
1471 \r
1472                 var Type returnType = null;\r
1473                 if(typeDef instanceof EnumTypeDefinition) {\r
1474                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);\r
1475                     val enumTypeDef = typeDef as EnumTypeDefinition;\r
1476                     val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, typeBuilder);\r
1477 \r
1478                     if(enumBuilder !== null) {\r
1479                         returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);\r
1480                     }\r
1481                     (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType);\r
1482                 } else if(typeDef instanceof UnionType) {\r
1483                     val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule);\r
1484                     if(genTOBuilder !== null) {\r
1485                         returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
1486                     }\r
1487                 } else if(typeDef instanceof BitsTypeDefinition) {\r
1488                     val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule);\r
1489                     if(genTOBuilder !== null) {\r
1490                         returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
1491                     }\r
1492                 } else {\r
1493                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);\r
1494                 }\r
1495                 if(returnType !== null) {\r
1496                     val MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType);\r
1497                     processContextRefExtension(leaf, getter, parentModule);\r
1498                     return true;\r
1499                 }\r
1500             }\r
1501         }\r
1502         return false;\r
1503     }\r
1504 \r
1505     private def void processContextRefExtension(LeafSchemaNode leaf, MethodSignatureBuilder getter, Module module) {\r
1506         for (node : leaf.unknownSchemaNodes) {\r
1507             val nodeType = node.nodeType;\r
1508             if ("context-reference".equals(nodeType.localName)) {\r
1509                 val nodeParam = node.nodeParameter;\r
1510                 var IdentitySchemaNode identity = null;\r
1511                 var String basePackageName = null;\r
1512                 val String[] splittedElement = nodeParam.split(":");\r
1513                 if (splittedElement.length == 1) {\r
1514                     identity = findIdentityByName(module.identities, splittedElement.get(0));\r
1515                     basePackageName = moduleNamespaceToPackageName(module);\r
1516                 } else if (splittedElement.length == 2) {\r
1517                     var prefix = splittedElement.get(0);\r
1518                     val Module dependentModule = findModuleFromImports(module.imports, prefix)\r
1519                     if (dependentModule == null) {\r
1520                         throw new IllegalArgumentException("Failed to process context-reference: unknown prefix " + prefix);\r
1521                     }\r
1522                     identity = findIdentityByName(dependentModule.identities, splittedElement.get(1));\r
1523                     basePackageName = moduleNamespaceToPackageName(dependentModule);\r
1524                 } else {\r
1525                     throw new IllegalArgumentException("Failed to process context-reference: unknown identity " + nodeParam);\r
1526                 }\r
1527                 if (identity == null) {\r
1528                     throw new IllegalArgumentException("Failed to process context-reference: unknown identity " + nodeParam);\r
1529                 }\r
1530 \r
1531                 val Class<RoutingContext> clazz = typeof(RoutingContext);\r
1532                 val AnnotationTypeBuilder rc = getter.addAnnotation(clazz.package.name, clazz.simpleName);\r
1533                 val packageName = packageNameForGeneratedType(basePackageName, identity.path);\r
1534                 val genTypeName = parseToClassName(identity.QName.localName);\r
1535                 rc.addParameter("value", packageName + "." + genTypeName + ".class");\r
1536             }\r
1537         }\r
1538     }\r
1539 \r
1540     private def IdentitySchemaNode findIdentityByName(Set<IdentitySchemaNode> identities, String name) {\r
1541         for (id : identities) {\r
1542             if (id.QName.localName.equals(name)) {\r
1543                 return id;\r
1544             }\r
1545         }\r
1546         return null;\r
1547     }\r
1548 \r
1549     private def Module findModuleFromImports(Set<ModuleImport> imports, String prefix) {\r
1550         for (imp : imports) {\r
1551             if (imp.prefix.equals(prefix)) {\r
1552                 return schemaContext.findModuleByName(imp.moduleName, imp.revision);\r
1553             }\r
1554         }\r
1555         return null;\r
1556     }\r
1557 \r
1558     /**\r
1559      * Converts <code>leaf</code> schema node to property of generated TO\r
1560      * builder.\r
1561      *\r
1562      * @param toBuilder\r
1563      *            generated TO builder to which is <code>leaf</code> added as\r
1564      *            property\r
1565      * @param leaf\r
1566      *            leaf schema node which is added to <code>toBuilder</code> as\r
1567      *            property\r
1568      * @param isReadOnly\r
1569      *            boolean value which says if leaf property is|isn't read only\r
1570      * @return boolean value\r
1571      *         <ul>\r
1572      *         <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf\r
1573      *         name equals null or if leaf is added by <i>uses</i>.</li>\r
1574      *         <li>true - other cases</li>\r
1575      *         </ul>\r
1576      */\r
1577     private def boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf,\r
1578         boolean isReadOnly) {\r
1579         if((leaf !== null) && (toBuilder !== null)) {\r
1580             val leafName = leaf.QName.localName;\r
1581             var String leafDesc = leaf.description;\r
1582             if(leafDesc === null) {\r
1583                 leafDesc = "";\r
1584             }\r
1585 \r
1586             if(leafName !== null) {\r
1587                 val TypeDefinition<?> typeDef = leaf.type;\r
1588 \r
1589                 // TODO: properly resolve enum types\r
1590                 val returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);\r
1591 \r
1592                 if(returnType !== null) {\r
1593                     val propBuilder = toBuilder.addProperty(parseToClassName(leafName));\r
1594 \r
1595                     propBuilder.setReadOnly(isReadOnly);\r
1596                     propBuilder.setReturnType(returnType);\r
1597                     propBuilder.setComment(leafDesc);\r
1598 \r
1599                     toBuilder.addEqualsIdentity(propBuilder);\r
1600                     toBuilder.addHashIdentity(propBuilder);\r
1601                     toBuilder.addToStringProperty(propBuilder);\r
1602 \r
1603                     return true;\r
1604                 }\r
1605             }\r
1606         }\r
1607         return false;\r
1608     }\r
1609 \r
1610     /**\r
1611      * Converts <code>node</code> leaf list schema node to getter method of\r
1612      * <code>typeBuilder</code>.\r
1613      *\r
1614      * @param typeBuilder\r
1615      *            generated type builder to which is <code>node</code> added as\r
1616      *            getter method\r
1617      * @param node\r
1618      *            leaf list schema node which is added to\r
1619      *            <code>typeBuilder</code> as getter method\r
1620      * @return boolean value\r
1621      *         <ul>\r
1622      *         <li>true - if <code>node</code>, <code>typeBuilder</code>,\r
1623      *         nodeName equal null or <code>node</code> is added by <i>uses</i></li>\r
1624      *         <li>false - other cases</li>\r
1625      *         </ul>\r
1626      */\r
1627     private def boolean resolveLeafListSchemaNode(GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) {\r
1628         if((node !== null) && (typeBuilder !== null)) {\r
1629             val nodeName = node.QName.localName;\r
1630             var String nodeDesc = node.description;\r
1631             if(nodeDesc === null) {\r
1632                 nodeDesc = "";\r
1633             }\r
1634 \r
1635             if(nodeName !== null && !node.isAddedByUses()) {\r
1636                 val TypeDefinition<?> type = node.type;\r
1637                 val listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type, node));\r
1638 \r
1639                 constructGetter(typeBuilder, nodeName, nodeDesc, listType);\r
1640                 return true;\r
1641             }\r
1642         }\r
1643         return false;\r
1644     }\r
1645 \r
1646     /**\r
1647      * Creates a getter method for a container node.\r
1648      *\r
1649      * Firstly generated type builder for container is created or found in\r
1650      * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name\r
1651      * in the builder is created as concatenation of module package name and\r
1652      * names of all parent nodes. In the end the getter method for container is\r
1653      * added to <code>typeBuilder</code> and return type is set to container\r
1654      * type builder.\r
1655      *\r
1656      * @param basePackageName\r
1657      *            string with the module package name\r
1658      * @param typeBuilder\r
1659      *            generated type builder to which is <code>containerNode</code>\r
1660      *            added as getter method\r
1661      * @param containerNode\r
1662      *            container schema node which is mapped as getter method to\r
1663      *            <code>typeBuilder</code>\r
1664      * @return boolean value\r
1665      *         <ul>\r
1666      *         <li>false - if <code>containerNode</code>,\r
1667      *         <code>typeBuilder</code>, container node name equal null or\r
1668      *         <code>containerNode</code> is added by uses</li>\r
1669      *         <li>true - other cases</li>\r
1670      *         </ul>\r
1671      */\r
1672     private def boolean resolveContainerSchemaNode(String basePackageName, GeneratedTypeBuilder typeBuilder,\r
1673         ContainerSchemaNode containerNode) {\r
1674         if((containerNode !== null) && (typeBuilder !== null)) {\r
1675             val nodeName = containerNode.QName.localName;\r
1676 \r
1677             if(nodeName !== null && !containerNode.isAddedByUses()) {\r
1678                 val packageName = packageNameForGeneratedType(basePackageName, containerNode.path);\r
1679 \r
1680                 val rawGenType = addDefaultInterfaceDefinition(packageName, containerNode);\r
1681                 constructGetter(typeBuilder, nodeName, containerNode.description, rawGenType);\r
1682 \r
1683                 return true;\r
1684             }\r
1685         }\r
1686         return false;\r
1687     }\r
1688 \r
1689     /**\r
1690      * Creates a getter method for a list node.\r
1691      *\r
1692      * Firstly generated type builder for list is created or found in\r
1693      * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name\r
1694      * in the builder is created as concatenation of module package name and\r
1695      * names of all parent nodes. In the end the getter method for list is added\r
1696      * to <code>typeBuilder</code> and return type is set to list type builder.\r
1697      *\r
1698      * @param basePackageName\r
1699      *            string with the module package name\r
1700      * @param typeBuilder\r
1701      *            generated type builder to which is <code></code> added as\r
1702      *            getter method\r
1703      * @param listNode\r
1704      *            list schema node which is mapped as getter method to\r
1705      *            <code>typeBuilder</code>\r
1706      * @return boolean value\r
1707      *         <ul>\r
1708      *         <li>false - if <code>listNode</code>, <code>typeBuilder</code>,\r
1709      *         list node name equal null or <code>listNode</code> is added by\r
1710      *         uses</li>\r
1711      *         <li>true - other cases</li>\r
1712      *         </ul>\r
1713      */\r
1714     private def boolean resolveListSchemaNode(String basePackageName, GeneratedTypeBuilder typeBuilder,\r
1715         ListSchemaNode listNode) {\r
1716         if((listNode !== null) && (typeBuilder !== null)) {\r
1717             val listName = listNode.QName.localName;\r
1718 \r
1719             if(listName !== null && !listNode.isAddedByUses()) {\r
1720                 val packageName = packageNameForGeneratedType(basePackageName, listNode.path);\r
1721                 val rawGenType = addDefaultInterfaceDefinition(packageName, listNode);\r
1722                 constructGetter(typeBuilder, listName, listNode.description, Types.listTypeFor(rawGenType));\r
1723                 return true;\r
1724             }\r
1725         }\r
1726         return false;\r
1727     }\r
1728 \r
1729     /**\r
1730      * Instantiates generated type builder with <code>packageName</code> and\r
1731      * <code>schemaNode</code>.\r
1732      *\r
1733      * The new builder always implements\r
1734      * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.<br />\r
1735      * If <code>schemaNode</code> is instance of GroupingDefinition it also\r
1736      * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable\r
1737      * Augmentable}.<br />\r
1738      * If <code>schemaNode</code> is instance of\r
1739      * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer\r
1740      * DataNodeContainer} it can also implement nodes which are specified in\r
1741      * <i>uses</i>.\r
1742      *\r
1743      * @param packageName\r
1744      *            string with the name of the package to which\r
1745      *            <code>schemaNode</code> belongs.\r
1746      * @param schemaNode\r
1747      *            schema node for which is created generated type builder\r
1748      * @return generated type builder <code>schemaNode</code>\r
1749      */\r
1750     private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) {\r
1751         val builder = addRawInterfaceDefinition(packageName, schemaNode, "");\r
1752         builder.addImplementsType(DATA_OBJECT);\r
1753         if(!(schemaNode instanceof GroupingDefinition)) {\r
1754             builder.addImplementsType(augmentable(builder));\r
1755         }\r
1756 \r
1757         if(schemaNode instanceof DataNodeContainer) {\r
1758             addImplementedInterfaceFromUses(schemaNode as DataNodeContainer, builder);\r
1759         }\r
1760 \r
1761         return builder;\r
1762     }\r
1763 \r
1764     /**\r
1765      * Wraps the calling of the same overloaded method.\r
1766      *\r
1767      * @param packageName\r
1768      *            string with the package name to which returning generated type\r
1769      *            builder belongs\r
1770      * @param schemaNode\r
1771      *            schema node which provide data about the schema node name\r
1772      * @return generated type builder for <code>schemaNode</code>\r
1773      */\r
1774     private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode) {\r
1775         return addRawInterfaceDefinition(packageName, schemaNode, "");\r
1776     }\r
1777 \r
1778     /**\r
1779      * Returns reference to generated type builder for specified\r
1780      * <code>schemaNode</code> with <code>packageName</code>.\r
1781      *\r
1782      * Firstly the generated type builder is searched in\r
1783      * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't\r
1784      * found it is created and added to <code>genTypeBuilders</code>.\r
1785      *\r
1786      * @param packageName\r
1787      *            string with the package name to which returning generated type\r
1788      *            builder belongs\r
1789      * @param schemaNode\r
1790      *            schema node which provide data about the schema node name\r
1791      * @return generated type builder for <code>schemaNode</code>\r
1792      * @throws IllegalArgumentException\r
1793      *             <ul>\r
1794      *             <li>if <code>schemaNode</code> equals null</li>\r
1795      *             <li>if <code>packageName</code> equals null</li>\r
1796      *             <li>if Q name of schema node is null</li>\r
1797      *             <li>if schema node name is nul</li>\r
1798      *             </ul>\r
1799      *\r
1800      */\r
1801     private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode,\r
1802         String prefix) {\r
1803         checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL.");\r
1804         checkArgument(packageName !== null, "Package Name for Generated Type cannot be NULL.");\r
1805         checkArgument(schemaNode.QName !== null, "QName for Data Schema Node cannot be NULL.");\r
1806         val schemaNodeName = schemaNode.QName.localName;\r
1807         checkArgument(schemaNodeName !== null, "Local Name of QName for Data Schema Node cannot be NULL.");\r
1808 \r
1809         var String genTypeName;\r
1810         if(prefix === null) {\r
1811             genTypeName = parseToClassName(schemaNodeName);\r
1812         } else {\r
1813             genTypeName = prefix + parseToClassName(schemaNodeName);\r
1814         }\r
1815 \r
1816         //FIXME: Validation of name conflict\r
1817         val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);\r
1818         yangToJavaMapping.put(schemaNode.path, newType);\r
1819         if(!genTypeBuilders.containsKey(packageName)) {\r
1820             val Map<String, GeneratedTypeBuilder> builders = new HashMap();\r
1821             builders.put(genTypeName, newType);\r
1822             genTypeBuilders.put(packageName, builders);\r
1823         } else {\r
1824             val Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);\r
1825             if(!builders.containsKey(genTypeName)) {\r
1826                 builders.put(genTypeName, newType);\r
1827             }\r
1828         }\r
1829         return newType;\r
1830     }\r
1831 \r
1832     /**\r
1833      * Creates the name of the getter method from <code>methodName</code>.\r
1834      *\r
1835      * @param methodName\r
1836      *            string with the name of the getter method\r
1837      * @return string with the name of the getter method for\r
1838      *         <code>methodName</code> in JAVA method format\r
1839      */\r
1840     private def String getterMethodName(String methodName, Type returnType) {\r
1841         val method = new StringBuilder();\r
1842         if(BOOLEAN.equals(returnType)) {\r
1843             method.append("is");\r
1844         } else {\r
1845             method.append("get");\r
1846         }\r
1847         method.append(parseToClassName(methodName));\r
1848         return method.toString();\r
1849     }\r
1850 \r
1851     /**\r
1852      * Created a method signature builder as part of\r
1853      * <code>interfaceBuilder</code>.\r
1854      *\r
1855      * The method signature builder is created for the getter method of\r
1856      * <code>schemaNodeName</code>. Also <code>comment</code> and\r
1857      * <code>returnType</code> information are added to the builder.\r
1858      *\r
1859      * @param interfaceBuilder\r
1860      *            generated type builder for which the getter method should be\r
1861      *            created\r
1862      * @param schemaNodeName\r
1863      *            string with schema node name. The name will be the part of the\r
1864      *            getter method name.\r
1865      * @param comment\r
1866      *            string with comment for the getter method\r
1867      * @param returnType\r
1868      *            type which represents the return type of the getter method\r
1869      * @return method signature builder which represents the getter method of\r
1870      *         <code>interfaceBuilder</code>\r
1871      */\r
1872     private def MethodSignatureBuilder constructGetter(GeneratedTypeBuilder interfaceBuilder, String schemaNodeName,\r
1873         String comment, Type returnType) {\r
1874 \r
1875         val getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName, returnType));\r
1876 \r
1877         getMethod.setComment(comment);\r
1878         getMethod.setReturnType(returnType);\r
1879 \r
1880         return getMethod;\r
1881     }\r
1882 \r
1883     /**\r
1884      * Adds <code>schemaNode</code> to <code>typeBuilder</code> as getter method\r
1885      * or to <code>genTOBuilder</code> as property.\r
1886      *\r
1887      * @param basePackageName\r
1888      *            string contains the module package name\r
1889      * @param schemaNode\r
1890      *            data schema node which should be added as getter method to\r
1891      *            <code>typeBuilder</code> or as a property to\r
1892      *            <code>genTOBuilder</code> if is part of the list key\r
1893      * @param typeBuilder\r
1894      *            generated type builder for the list schema node\r
1895      * @param genTOBuilder\r
1896      *            generated TO builder for the list keys\r
1897      * @param listKeys\r
1898      *            list of string which contains names of the list keys\r
1899      * @throws IllegalArgumentException\r
1900      *             <ul>\r
1901      *             <li>if <code>schemaNode</code> equals null</li>\r
1902      *             <li>if <code>typeBuilder</code> equals null</li>\r
1903      *             </ul>\r
1904      */\r
1905     private def void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode,\r
1906         GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List<String> listKeys) {\r
1907         checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL.");\r
1908 \r
1909         checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL.");\r
1910 \r
1911         if(schemaNode instanceof LeafSchemaNode) {\r
1912             val leaf = schemaNode as LeafSchemaNode;\r
1913             val leafName = leaf.QName.localName;\r
1914             if(!listKeys.contains(leafName)) {\r
1915                 resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);\r
1916             } else {\r
1917                 resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);\r
1918             }\r
1919         } else if(schemaNode instanceof LeafListSchemaNode) {\r
1920             resolveLeafListSchemaNode(typeBuilder, schemaNode as LeafListSchemaNode);\r
1921         } else if(schemaNode instanceof ContainerSchemaNode) {\r
1922             resolveContainerSchemaNode(basePackageName, typeBuilder, schemaNode as ContainerSchemaNode);\r
1923         } else if(schemaNode instanceof ChoiceNode) {\r
1924             resolveChoiceSchemaNode(basePackageName,typeBuilder,schemaNode as ChoiceNode);\r
1925         } else if(schemaNode instanceof ListSchemaNode) {\r
1926             resolveListSchemaNode(basePackageName, typeBuilder, schemaNode as ListSchemaNode);\r
1927         }\r
1928     }\r
1929 \r
1930     private def typeBuildersToGenTypes(GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) {\r
1931         val List<Type> genTypes = new ArrayList();\r
1932         checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL.");\r
1933 \r
1934         if(genTOBuilder !== null) {\r
1935             val genTO = genTOBuilder.toInstance();\r
1936             constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO);\r
1937             genTypes.add(genTO);\r
1938         }\r
1939         genTypes.add(typeBuilder.toInstance());\r
1940         return genTypes;\r
1941     }\r
1942 \r
1943     /**\r
1944      * Selects the names of the list keys from <code>list</code> and returns\r
1945      * them as the list of the strings\r
1946      *\r
1947      * @param list\r
1948      *            of string with names of the list keys\r
1949      * @return list of string which represents names of the list keys. If the\r
1950      *         <code>list</code> contains no keys then the empty list is\r
1951      *         returned.\r
1952      */\r
1953     private def listKeys(ListSchemaNode list) {\r
1954         val List<String> listKeys = new ArrayList();\r
1955 \r
1956         if(list.keyDefinition !== null) {\r
1957             val keyDefinitions = list.keyDefinition;\r
1958             for (keyDefinition : keyDefinitions) {\r
1959                 listKeys.add(keyDefinition.localName);\r
1960             }\r
1961         }\r
1962         return listKeys;\r
1963     }\r
1964 \r
1965     /**\r
1966      * Generates for the <code>list</code> which contains any list keys special\r
1967      * generated TO builder.\r
1968      *\r
1969      * @param packageName\r
1970      *            string with package name to which the list belongs\r
1971      * @param list\r
1972      *            list schema node which is source of data about the list name\r
1973      * @return generated TO builder which represents the keys of the\r
1974      *         <code>list</code> or null if <code>list</code> is null or list of\r
1975      *         key definitions is null or empty.\r
1976      */\r
1977     private def GeneratedTOBuilder resolveListKeyTOBuilder(String packageName, ListSchemaNode list) {\r
1978         var GeneratedTOBuilder genTOBuilder = null;\r
1979         if((list.keyDefinition !== null) && (!list.keyDefinition.isEmpty())) {\r
1980             if(list !== null) {\r
1981                 val listName = list.QName.localName + "Key";\r
1982                 val String genTOName = parseToClassName(listName);\r
1983                 genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName);\r
1984             }\r
1985         }\r
1986         return genTOBuilder;\r
1987 \r
1988     }\r
1989 \r
1990     /**\r
1991      * Builds generated TO builders for <code>typeDef</code> of type\r
1992      * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or\r
1993      * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition\r
1994      * BitsTypeDefinition} which are also added to <code>typeBuilder</code> as\r
1995      * enclosing transfer object.\r
1996      *\r
1997      * If more then one generated TO builder is created for enclosing then all\r
1998      * of the generated TO builders are added to <code>typeBuilder</code> as\r
1999      * enclosing transfer objects.\r
2000      *\r
2001      * @param typeDef\r
2002      *            type definition which can be of type <code>UnionType</code> or\r
2003      *            <code>BitsTypeDefinition</code>\r
2004      * @param typeBuilder\r
2005      *            generated type builder to which is added generated TO created\r
2006      *            from <code>typeDef</code>\r
2007      * @param leafName\r
2008      *            string with name for generated TO builder\r
2009      * @return generated TO builder for <code>typeDef</code>\r
2010      */\r
2011     private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,\r
2012         String leafName, LeafSchemaNode leaf, Module parentModule) {\r
2013         val classNameFromLeaf = parseToClassName(leafName);\r
2014         val List<GeneratedTOBuilder> genTOBuilders = new ArrayList();\r
2015         val packageName = typeBuilder.fullyQualifiedName;\r
2016         if(typeDef instanceof UnionTypeDefinition) {\r
2017             genTOBuilders.addAll(\r
2018                 (typeProvider as TypeProviderImpl).\r
2019                     provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition),\r
2020                         classNameFromLeaf, leaf));\r
2021         } else if(typeDef instanceof BitsTypeDefinition) {\r
2022             genTOBuilders.add(\r
2023                 ((typeProvider as TypeProviderImpl) ).\r
2024                     provideGeneratedTOBuilderForBitsTypeDefinition(packageName, typeDef, classNameFromLeaf));\r
2025         }\r
2026         if(genTOBuilders !== null && !genTOBuilders.isEmpty()) {\r
2027             for (genTOBuilder : genTOBuilders) {\r
2028                 typeBuilder.addEnclosingTransferObject(genTOBuilder);\r
2029             }\r
2030             return genTOBuilders.get(0);\r
2031         }\r
2032         return null;\r
2033 \r
2034     }\r
2035 \r
2036     /**\r
2037      * Adds the implemented types to type builder.\r
2038      *\r
2039      * The method passes through the list of <i>uses</i> in\r
2040      * {@code dataNodeContainer}. For every <i>use</i> is obtained coresponding\r
2041      * generated type from {@link BindingGeneratorImpl#allGroupings\r
2042      * allGroupings} which is added as <i>implements type</i> to\r
2043      * <code>builder</code>\r
2044      *\r
2045      * @param dataNodeContainer\r
2046      *            element which contains the list of used YANG groupings\r
2047      * @param builder\r
2048      *            builder to which are added implemented types according to\r
2049      *            <code>dataNodeContainer</code>\r
2050      * @return generated type builder with all implemented types\r
2051      */\r
2052     private def addImplementedInterfaceFromUses(DataNodeContainer dataNodeContainer, GeneratedTypeBuilder builder) {\r
2053         for (usesNode : dataNodeContainer.uses) {\r
2054             if(usesNode.groupingPath !== null) {\r
2055                 val genType = allGroupings.get(usesNode.groupingPath);\r
2056                 if(genType === null) {\r
2057                     throw new IllegalStateException(\r
2058                         "Grouping " + usesNode.groupingPath + "is not resolved for " + builder.name);\r
2059                 }\r
2060                 builder.addImplementsType(genType);\r
2061             }\r
2062         }\r
2063         return builder;\r
2064     }\r
2065 }\r