Binding generator v2 - uses statement - support list
[mdsal.git] / binding2 / mdsal-binding2-generator-impl / src / main / java / org / opendaylight / mdsal / binding / javav2 / generator / impl / GenHelperUtil.java
index 146893bf3821f3d3e8980e9a4cfb9efcd560f8c1..8f45aacbb94e16cc3f70fc03cd79772be86a154c 100644 (file)
@@ -20,11 +20,13 @@ import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenU
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.qNameConstant;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveInnerEnumFromTypeDefinition;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveListKeyTOBuilder;
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveListKeyTypeBuilder;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.computeDefaultSUID;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.parameterizedTypeFor;
+import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.wildcardTypeFor;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
 
@@ -282,7 +284,6 @@ final class GenHelperUtil {
         return genCtx;
     }
 
-
     static void addUsesImplements(final DataNodeContainer superNode, final Module superModule,
             final DataNodeContainer node, final Module module,
             final SchemaContext schemaContext, Map<Module, ModuleContext> genCtx, final BindingNamespaceType namespaceType ) {
@@ -302,6 +303,16 @@ final class GenHelperUtil {
                 Preconditions.checkNotNull(type, module.toString() + "->" + childNode.getPath().toString());
                 Preconditions.checkNotNull(superType, superModule.toString() + "->" + superChildNode.getPath().toString());
                 type.addImplementsType(superType);
+                if (superChildNode instanceof ListSchemaNode
+                        && !((ListSchemaNode)superChildNode).getKeyDefinition().isEmpty()) {
+                    if (namespaceType.equals(BindingNamespaceType.Grouping)) {
+                        genCtx.get(module).getKeyType(childNode.getPath())
+                                .addImplementsType(genCtx.get(superModule).getKeyType(superChildNode.getPath()));
+                    } else if (namespaceType.equals(BindingNamespaceType.Data)){
+                        genCtx.get(module).getKeyGenTO(childNode.getPath())
+                                .addImplementsType(genCtx.get(superModule).getKeyType(superChildNode.getPath()));
+                    }
+                }
                 addUsesImplements((DataNodeContainer)superChildNode, superModule, (DataNodeContainer)childNode, module, schemaContext, genCtx, namespaceType);
             }
         }
@@ -343,6 +354,16 @@ final class GenHelperUtil {
         return null;
     }
 
+    static GeneratedTypeBuilder findKeyByPath(final SchemaPath path, final Map<Module, ModuleContext> genCtx) {
+        for (final ModuleContext ctx : genCtx.values()) {
+            final GeneratedTypeBuilder result = ctx.getKeyType(path);
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
     static Map<Module, ModuleContext> addRawAugmentGenTypeDefinition(final Module module, final String augmentPackageName,
             final Type targetTypeRef, final List<AugmentationSchema> schemaPathAugmentListEntry,
             final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final Map<Module, ModuleContext> genCtx,
@@ -710,38 +731,64 @@ final class GenHelperUtil {
                 schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
         if (genType != null) {
             final String nodeName = node.getQName().getLocalName();
-            constructGetter(parent, nodeName, node.getDescription(), Types.listTypeFor(genType), node.getStatus());
+
+            Type getterReturnType = Types.listTypeFor(genType);
+            if (namespaceType.equals(BindingNamespaceType.Grouping)) {
+                getterReturnType = Types.listTypeFor(wildcardTypeFor(genType.getPackageName(), genType.getName(),
+                                true, true));
+            }
+            constructGetter(parent, nodeName, node.getDescription(), getterReturnType, node.getStatus());
+
             final List<QName> listKeys = node.getKeyDefinition();
             final String packageName = new StringBuilder(packageNameForGeneratedType(basePackageName, node.getPath(),
                     BindingNamespaceType.Key)).append('.').append(nodeName).toString();
+            //FIXME: Is it neccessary to generate interface of key and implemented by class?
+            if (namespaceType.equals(BindingNamespaceType.Grouping)) {
+                final GeneratedTypeBuilder genTypeBuilder = resolveListKeyTypeBuilder(packageName, node);
+                for (final DataSchemaNode schemaNode : node.getChildNodes()) {
+                    if (!schemaNode.isAugmenting()) {
+                        addSchemaNodeToListTypeBuilders(nodeName, basePackageName, schemaNode, genType, genTypeBuilder, listKeys,
+                                module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, namespaceType);
+                    }
+                }
+                if (genTypeBuilder != null) {
+                    typeBuildersToGenTypes(module, genType, genTypeBuilder.toInstance(), genCtx, namespaceType);
+                    genCtx.get(module).addKeyType(node.getPath(), genTypeBuilder);
+                }
+            } else {
+                final GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, node);
+                for (final DataSchemaNode schemaNode : node.getChildNodes()) {
+                    if (!schemaNode.isAugmenting()) {
+                        addSchemaNodeToListBuilders(nodeName, basePackageName, schemaNode, genType, genTOBuilder, listKeys,
+                                module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, namespaceType);
+                    }
+                }
 
-            final GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, node);
+                // serialVersionUID
+                if (genTOBuilder != null) {
+                    final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");
+                    prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder)));
+                    genTOBuilder.setSUID(prop);
 
-            for (final DataSchemaNode schemaNode : node.getChildNodes()) {
-                if (!schemaNode.isAugmenting()) {
-                    addSchemaNodeToListBuilders(nodeName, basePackageName, schemaNode, genType, genTOBuilder, listKeys,
-                            module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, namespaceType);
+                    typeBuildersToGenTypes(module, genType, genTOBuilder.toInstance(), genCtx, namespaceType);
+                    genCtx.get(module).addGeneratedTOBuilder(node.getPath(), genTOBuilder);
                 }
             }
-
-            // serialVersionUID
-            if (genTOBuilder != null) {
-                final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");
-                prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder)));
-                genTOBuilder.setSUID(prop);
-            }
-
-            typeBuildersToGenTypes(module, genType, genTOBuilder, genCtx);
         }
     }
 
     private static void typeBuildersToGenTypes(final Module module, final GeneratedTypeBuilder typeBuilder,
-            final GeneratedTOBuilder genTOBuilder, final Map<Module, ModuleContext> genCtx) {
+            final Type keyType, final Map<Module, ModuleContext> genCtx,
+            final BindingNamespaceType namespaceType) {
         checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL.");
-        if (genTOBuilder != null) {
-            final GeneratedTransferObject genTO = genTOBuilder.toInstance();
-            constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO, Status.CURRENT);
-            genCtx.get(module).addGeneratedTOBuilder(genTOBuilder);
+        if (keyType != null) {
+            Type returnKeyType = keyType;
+            if (namespaceType.equals(BindingNamespaceType.Grouping)) {
+                returnKeyType = wildcardTypeFor(keyType.getPackageName(), keyType.getName(),
+                        true, true);
+            }
+            constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", returnKeyType, Status.CURRENT);
+
         }
     }
 
@@ -1081,13 +1128,48 @@ final class GenHelperUtil {
                     typeProvider);
             if (listKeys.contains(leafQName)) {
                 if (type == null) {
-                    resolveLeafSchemaNodeAsProperty(schemaContext, typeProvider, genCtx, genTOBuilder, leaf, true,
+                    resolveLeafSchemaNodeAsProperty(nodeName, schemaContext, typeProvider, genCtx, genTOBuilder, leaf, true,
                         module);
                 } else {
-                    AuxiliaryGenUtils.resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, type, true);
+                    AuxiliaryGenUtils.resolveLeafSchemaNodeAsProperty(nodeName, genTOBuilder, leaf, type, true);
                 }
             }
-        } else if (!schemaNode.isAddedByUses()) {
+        } else {
+            if (schemaNode instanceof LeafListSchemaNode) {
+                resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) schemaNode, module,
+                        typeProvider, genCtx);
+            } else if (schemaNode instanceof ContainerSchemaNode) {
+                containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode,
+                        schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
+            } else if (schemaNode instanceof ListSchemaNode) {
+                listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode,
+                        schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
+            } else if (schemaNode instanceof ChoiceSchemaNode) {
+                choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder,
+                        (ChoiceSchemaNode) schemaNode, genTypeBuilders, genCtx, typeProvider, namespaceType);
+            }
+        }
+    }
+
+    private static void addSchemaNodeToListTypeBuilders(final String nodeName, final String basePackageName,
+                                                    final DataSchemaNode schemaNode, final GeneratedTypeBuilder typeBuilder,
+                                                    final GeneratedTypeBuilder genTypeBuilder, final List<QName> listKeys, final Module module,
+                                                    final TypeProvider typeProvider, final SchemaContext schemaContext, final Map<Module, ModuleContext> genCtx,
+                                                    final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final boolean verboseClassComments,
+                                                    final BindingNamespaceType namespaceType) {
+        checkArgument(schemaNode != null, "Data Schema Node cannot be NULL.");
+        checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL.");
+
+        if (schemaNode instanceof LeafSchemaNode) {
+            final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
+            final QName leafQName = leaf.getQName();
+            final Type type = resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, typeBuilder, genCtx, leaf, module,
+                    typeProvider);
+            if (listKeys.contains(leafQName)) {
+                resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, genTypeBuilder, genCtx, leaf, module,
+                        typeProvider);
+            }
+        } else {
             if (schemaNode instanceof LeafListSchemaNode) {
                 resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) schemaNode, module,
                         typeProvider, genCtx);
@@ -1104,7 +1186,7 @@ final class GenHelperUtil {
         }
     }
 
-    private static boolean resolveLeafSchemaNodeAsProperty(final SchemaContext schemaContext, final TypeProvider
+    private static boolean resolveLeafSchemaNodeAsProperty(final String nodeName, final SchemaContext schemaContext, final TypeProvider
             typeProvider, final Map<Module, ModuleContext> genCtx, final GeneratedTOBuilder
             toBuilder, final LeafSchemaNode leaf, final boolean isReadOnly, final Module module) {
 
@@ -1129,7 +1211,7 @@ final class GenHelperUtil {
             } else {
                 returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
             }
-            return AuxiliaryGenUtils.resolveLeafSchemaNodeAsProperty(toBuilder, leaf, returnType, isReadOnly);
+            return AuxiliaryGenUtils.resolveLeafSchemaNodeAsProperty(nodeName, toBuilder, leaf, returnType, isReadOnly);
         }
         return false;
     }