Binding generator v2 - uses statement - uses inner type #2 95/61595/1
authorJie Han <han.jie@zte.com.cn>
Tue, 18 Jul 2017 10:56:25 +0000 (18:56 +0800)
committerJie Han <han.jie@zte.com.cn>
Mon, 14 Aug 2017 08:11:55 +0000 (16:11 +0800)
- for current implementation of yangtools does not copy "types" from groupings,
but the original definition of a type is reused, so we should find inner type
added by uses by original node.
  this patch should be merged with:
  - https://git.opendaylight.org/gerrit/60529
  - https://git.opendaylight.org/gerrit/60582
- support uses leaf with inner type union, bits
- add yangs and test

Change-Id: Ibee57eb030a79e6ce06bb371e82257b7ab58ab98
Signed-off-by: Jie Han <han.jie@zte.com.cn>
(cherry picked from commit 3c24618b19b500ead3091dc9858baf7c57b79a47)

binding2/mdsal-binding2-generator-api/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/context/ModuleContext.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AuxiliaryGenUtils.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/yang/types/TypeProviderImpl.java
binding2/mdsal-binding2-generator-impl/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AuxiliaryGenUtilsTest.java
binding2/mdsal-binding2-generator-impl/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/impl/BindingGeneratorImplTest.java
binding2/mdsal-binding2-generator-impl/src/test/resources/uses-statement/test-uses-leaf-innertype2-base.yang [new file with mode: 0644]
binding2/mdsal-binding2-generator-impl/src/test/resources/uses-statement/test-uses-leaf-innertype2.yang [new file with mode: 0644]

index d2f8aa21abcdf4bb90bc7dd8e97b949b68bf0648..c2725730dd03f24c60015f7c1ba5094f3e93fe84 100644 (file)
@@ -26,7 +26,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
-import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -214,13 +213,13 @@ public final class ModuleContext {
     }
 
     /**
-     * Adds mapping between schema path and inner enum.
+     * Adds mapping between schema path and inner enum, inner union, inner bits.
      *
      * @param path
-     * @param enumBuilder
+     * @param builder
      */
-    public void addInnerTypedefType(final SchemaPath path, final EnumBuilder enumBuilder) {
-        this.innerTypes.put(path, enumBuilder);
+    public void addInnerTypedefType(final SchemaPath path, final Type builder) {
+        this.innerTypes.put(path, builder);
     }
 
     public Type getInnerType(final SchemaPath path) {
index 980ae343bbaeb6855e9bd418f23842d726ae34fd..b5e881bf6bd5072a54981db16536f901de1afa32 100644 (file)
@@ -388,7 +388,7 @@ final class AuxiliaryGenUtils {
      */
     static GeneratedTOBuilder addTOToTypeBuilder(final TypeDefinition<?> typeDef, final GeneratedTypeBuilder
             typeBuilder, final DataSchemaNode leaf, final Module parentModule, final TypeProvider typeProvider,
-            final SchemaContext schemaContext, ModuleContext context) {
+            final SchemaContext schemaContext, ModuleContext context, final Map<Module, ModuleContext> genCtx) {
         final String classNameFromLeaf = leaf.getQName().getLocalName();
         GeneratedTOBuilder genTOBuilder = null;
         final String packageName = typeBuilder.getFullyQualifiedName();
@@ -403,6 +403,7 @@ final class AuxiliaryGenUtils {
         }
         if (genTOBuilder != null) {
             typeBuilder.addEnclosingTransferObject(genTOBuilder);
+            genCtx.get(parentModule).addInnerTypedefType(typeDef.getPath(), genTOBuilder);
             return genTOBuilder;
         }
         return null;
index a261112ffe2fe1bf731f7572121cd2b65a215ef1..585e1592b1ef906c1121388206cf6f024b573ff6 100644 (file)
@@ -60,7 +60,6 @@ import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
-import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
 import org.opendaylight.mdsal.binding.javav2.spec.base.BaseIdentity;
 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
@@ -742,7 +741,7 @@ final class GenHelperUtil {
                 schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
         if (genType != null) {
             StringBuilder getterName = new StringBuilder(node.getQName().getLocalName());
-            final MethodSignatureBuilder getter = constructGetter(parent, getterName.toString(), node.getDescription(), genType, node.getStatus());
+            constructGetter(parent, getterName.toString(), node.getDescription(), genType, node.getStatus());
             resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes(), genCtx,
                     schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
             processUsesImplements(node, module, schemaContext, genCtx, namespaceType);
@@ -862,7 +861,15 @@ final class GenHelperUtil {
             LeafSchemaNode originalLeaf = (LeafSchemaNode)((DerivableSchemaNode) leaf).getOriginal().orNull();
             Preconditions.checkNotNull(originalLeaf);
             if (isInnerType(originalLeaf, typeDef)) {
-                returnType = genCtx.get(findParentModule(schemaContext, originalLeaf)).getInnerType(typeDef.getPath());
+                if (typeDef instanceof EnumTypeDefinition
+                        || typeDef instanceof UnionTypeDefinition
+                        || typeDef instanceof BitsTypeDefinition) {
+                    returnType = genCtx.get(findParentModule(schemaContext, originalLeaf)).getInnerType(typeDef.getPath());
+                } else {
+                    final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(getBaseOrDeclaredType(typeDef), leaf,
+                            restrictions, genCtx.get(module));
+                }
             } else {
                 final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
                 returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions, genCtx.get(module));
@@ -879,14 +886,14 @@ final class GenHelperUtil {
                 ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
             } else if (typeDef instanceof UnionTypeDefinition) {
                 final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule,
-                        typeProvider, schemaContext, genCtx.get(module));
+                        typeProvider, schemaContext, genCtx.get(module), genCtx);
                 if (genTOBuilder != null) {
                     //TODO: https://bugs.opendaylight.org/show_bug.cgi?id=2289
                     returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider);
                 }
             } else if (typeDef instanceof BitsTypeDefinition) {
                 final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule,
-                        typeProvider, schemaContext, genCtx.get(module));
+                        typeProvider, schemaContext, genCtx.get(module), genCtx);
                 if (genTOBuilder != null) {
                     returnType = genTOBuilder.toInstance();
                 }
@@ -974,13 +981,13 @@ final class GenHelperUtil {
                 ((TypeProviderImpl) typeProvider).putReferencedType(node.getPath(), returnType);
             } else if (typeDef instanceof UnionTypeDefinition) {
                 final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule,
-                        typeProvider, schemaContext, genCtx.get(module));
+                        typeProvider, schemaContext, genCtx.get(module), genCtx);
                 if (genTOBuilder != null) {
                     returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider);
                 }
             } else if (typeDef instanceof BitsTypeDefinition) {
                 final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule,
-                        typeProvider, schemaContext, genCtx.get(module));
+                        typeProvider, schemaContext, genCtx.get(module), genCtx);
                 returnType = genTOBuilder.toInstance();
             } else {
                 final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
index 88ff434cd50cba53051685bf2dfd22049a3622d1..e168fab00db1d01fa8418803dd24b08968745ab9 100644 (file)
@@ -436,7 +436,7 @@ public final class TypeProviderImpl implements TypeProvider {
             // a base type which holds these constraints.
             if (typeDefinition instanceof DecimalTypeDefinition) {
                 final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType
-                        (typeDefinition, parentNode, r, null);
+                        (typeDefinition, parentNode, r, context);
                 if (ret != null) {
                     return ret;
                 }
index bb43516d6df0d0a669d21086c19f6e6d84d0ccfe..f43d0caca3c2a0a9f07d494eabf6700e45860b38 100644 (file)
@@ -441,7 +441,7 @@ public class AuxiliaryGenUtilsTest {
     public void addTOToTypeBuilderNullTest() throws Exception {
         final Class[] parameterTypes =
                 { TypeDefinition.class, GeneratedTypeBuilder.class, DataSchemaNode.class, Module.class,
-                        TypeProvider.class, SchemaContext.class, ModuleContext.class };
+                        TypeProvider.class, SchemaContext.class, ModuleContext.class, Map.class };
         final Method generate = AuxiliaryGenUtils.class.getDeclaredMethod("addTOToTypeBuilder", parameterTypes);
         assertNotNull(generate);
         generate.setAccessible(true);
@@ -457,8 +457,10 @@ public class AuxiliaryGenUtilsTest {
         final Set<Module> modules = new HashSet<>();
         when(schemaContext.getModules()).thenReturn(modules);
         final TypeProviderImpl typeProvider = new TypeProviderImpl(schemaContext);
+        final Map<Module, ModuleContext> genCtx = new HashMap<>();
+        genCtx.put(parentModule, new ModuleContext());
 
-        final Object[] args1 = { typeDef, typeBuilder, leaf, parentModule, typeProvider, schemaContext, new ModuleContext() };
+        final Object[] args1 = { typeDef, typeBuilder, leaf, parentModule, typeProvider, schemaContext, new ModuleContext(), genCtx };
         final GeneratedTOBuilder result = (GeneratedTOBuilder) generate.invoke(AuxiliaryGenUtils.class, args1);
         assertEquals(null, result);
     }
@@ -478,7 +480,7 @@ public class AuxiliaryGenUtilsTest {
             throws NoSuchMethodException, ReactorException, FileNotFoundException, URISyntaxException,
             IllegalAccessException, InvocationTargetException {
         final Class[] parameterTypes = { TypeDefinition.class, GeneratedTypeBuilder.class, DataSchemaNode.class,
-                Module.class, TypeProvider.class, SchemaContext.class, ModuleContext.class };
+                Module.class, TypeProvider.class, SchemaContext.class, ModuleContext.class, Map.class };
         final Method generate = AuxiliaryGenUtils.class.getDeclaredMethod("addTOToTypeBuilder", parameterTypes);
         assertNotNull(generate);
         generate.setAccessible(true);
@@ -490,8 +492,11 @@ public class AuxiliaryGenUtilsTest {
         final LeafSchemaNode leafSchemaNode =
                 (LeafSchemaNode) schemaContext.getModules().iterator().next().getChildNodes().iterator().next();
         final TypeDefinition<? extends TypeDefinition<?>> typeDef = leafSchemaNode.getType();
+        final Map<Module, ModuleContext> genCtx = new HashMap<>();
+        genCtx.put(schemaContext.getModules().iterator().next(), new ModuleContext());
+
         final Object[] args1 = { typeDef, typeBuilder, leafSchemaNode, schemaContext.getModules().iterator().next(),
-                typeProvider, schemaContext, new ModuleContext() };
+                typeProvider, schemaContext, new ModuleContext(), genCtx };
         return (GeneratedTOBuilder) generate.invoke(AuxiliaryGenUtils.class, args1);
     }
 
index 201c3ec5a79ef5eb42f93ce89c4b4e106c5a108c..a0187c22b98082a4592c80f434fb07d522b4bfd7 100644 (file)
@@ -97,6 +97,108 @@ public class BindingGeneratorImplTest {
         }
     }
 
+    @Test
+    public void generatedTypesUsesBitsLeafTest() throws Exception {
+        final BindingGenerator bg = new BindingGeneratorImpl(false);
+        final List<String> sources = new ArrayList<>();
+        sources.add("/uses-statement/test-uses-leaf-innertype2-base.yang");
+        sources.add("/uses-statement/test-uses-leaf-innertype2.yang");
+        final SchemaContext context = YangParserTestUtils.parseYangSources(sources);
+        final List<Type> generateTypes = bg.generateTypes(context);
+        assertNotNull(generateTypes);
+        assertTrue(!generateTypes.isEmpty());
+        for (final Type type : generateTypes) {
+            if (type.getName().equals("MyCont") && type.getPackageName()
+                    .equals("org.opendaylight.mdsal.gen.javav2.urn.test.uses.leaf.innertype2.base.rev170809.data")) {
+                final GeneratedType gt = (GeneratedType) type;
+                for (MethodSignature methodSignature : gt.getMethodDefinitions()) {
+                    if (methodSignature.getName().equals("getLeafBits")) {
+                        assertEquals("LeafBits", methodSignature.getReturnType().getName());
+                    }
+                }
+
+            }
+
+            if (type.getName().equals("MyCont") && type.getPackageName()
+                    .equals("org.opendaylight.mdsal.gen.javav2.urn.test.uses.leaf.innertype2.rev170809.data")) {
+                final GeneratedType gt = (GeneratedType) type;
+                for (MethodSignature methodSignature : gt.getMethodDefinitions()) {
+                    if (methodSignature.getName().equals("getLeafBits")) {
+                        assertEquals("LeafBits", methodSignature.getReturnType().getName());
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    public void generatedTypesUsesUnionLeafTest() throws Exception {
+        final BindingGenerator bg = new BindingGeneratorImpl(false);
+        final List<String> sources = new ArrayList<>();
+        sources.add("/uses-statement/test-uses-leaf-innertype2-base.yang");
+        sources.add("/uses-statement/test-uses-leaf-innertype2.yang");
+        final SchemaContext context = YangParserTestUtils.parseYangSources(sources);
+        final List<Type> generateTypes = bg.generateTypes(context);
+        assertNotNull(generateTypes);
+        assertTrue(!generateTypes.isEmpty());
+        for (final Type type : generateTypes) {
+            if (type.getName().equals("MyCont") && type.getPackageName()
+                    .equals("org.opendaylight.mdsal.gen.javav2.urn.test.uses.leaf.innertype2.base.rev170809.data")) {
+                final GeneratedType gt = (GeneratedType) type;
+                for (MethodSignature methodSignature : gt.getMethodDefinitions()) {
+                    if (methodSignature.getName().equals("getLeafUnion")) {
+                        assertEquals("LeafUnion", methodSignature.getReturnType().getName());
+                    }
+                }
+
+            }
+
+            if (type.getName().equals("MyCont") && type.getPackageName()
+                    .equals("org.opendaylight.mdsal.gen.javav2.urn.test.uses.leaf.innertype2.rev170809.data")) {
+                final GeneratedType gt = (GeneratedType) type;
+                for (MethodSignature methodSignature : gt.getMethodDefinitions()) {
+                    if (methodSignature.getName().equals("getLeafUnion")) {
+                        assertEquals("LeafUnion", methodSignature.getReturnType().getName());
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    public void generatedTypesUsesLeafTest() throws Exception {
+        final BindingGenerator bg = new BindingGeneratorImpl(false);
+        final List<String> sources = new ArrayList<>();
+        sources.add("/uses-statement/test-uses-leaf-innertype2-base.yang");
+        sources.add("/uses-statement/test-uses-leaf-innertype2.yang");
+        final SchemaContext context = YangParserTestUtils.parseYangSources(sources);
+        final List<Type> generateTypes = bg.generateTypes(context);
+        assertNotNull(generateTypes);
+        assertTrue(!generateTypes.isEmpty());
+        for (final Type type : generateTypes) {
+            if (type.getName().equals("MyCont") && type.getPackageName()
+                    .equals("org.opendaylight.mdsal.gen.javav2.urn.test.uses.leaf.innertype2.base.rev170809.data")) {
+                final GeneratedType gt = (GeneratedType) type;
+                for (MethodSignature methodSignature : gt.getMethodDefinitions()) {
+                    if (methodSignature.getName().equals("getLeafDecimal64")) {
+                        assertEquals("BigDecimal", methodSignature.getReturnType().getName());
+                    }
+                }
+
+            }
+
+            if (type.getName().equals("MyCont") && type.getPackageName()
+                    .equals("org.opendaylight.mdsal.gen.javav2.urn.test.uses.leaf.innertype2.rev170809.data")) {
+                final GeneratedType gt = (GeneratedType) type;
+                for (MethodSignature methodSignature : gt.getMethodDefinitions()) {
+                    if (methodSignature.getName().equals("getLeafDecimal64")) {
+                        assertEquals("BigDecimal", methodSignature.getReturnType().getName());
+                    }
+                }
+            }
+        }
+    }
+
     @Test
     public void generatedTypesTest() throws Exception {
         final BindingGenerator bg = new BindingGeneratorImpl(false);
diff --git a/binding2/mdsal-binding2-generator-impl/src/test/resources/uses-statement/test-uses-leaf-innertype2-base.yang b/binding2/mdsal-binding2-generator-impl/src/test/resources/uses-statement/test-uses-leaf-innertype2-base.yang
new file mode 100644 (file)
index 0000000..72c06cf
--- /dev/null
@@ -0,0 +1,58 @@
+module test-uses-leaf-innertype2-base {
+    namespace "urn:test:uses:leaf:innertype2:base";
+    prefix uses-leaf;
+    revision 2017-08-09;
+
+    grouping my-grp {
+      leaf leaf-decimal64 {
+        description
+          "Minimum LSP Bandwidth. Units in bytes per second";
+        type decimal64 {
+          fraction-digits 2;
+        }
+      }
+
+      leaf leaf-union {
+        type union {
+          type int32;
+          type string;
+        }
+      }
+
+      leaf leaf-bits {
+        type bits {
+          bit path-computation-with-gmpls-link-constraints {
+            position 0;
+          }
+          bit bidirectional-path-computation {
+            position 1;
+          }
+          bit diverse-path-computation {
+            position 2;
+          }
+          bit load-balanced-path-computation {
+            position 3;
+          }
+          bit synchronized-path-computation {
+            position 4;
+          }
+          bit support-for-multiple-objective-functions {
+            position 5;
+          }
+          bit support-for-additive-path-constraints {
+            position 6;
+          }
+          bit support-for-request-prioritization {
+            position 7;
+          }
+          bit support-for-multiple-requests-per-message {
+            position 8;
+          }
+        }
+      }
+    }
+
+    container my-cont {
+      uses my-grp;
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-generator-impl/src/test/resources/uses-statement/test-uses-leaf-innertype2.yang b/binding2/mdsal-binding2-generator-impl/src/test/resources/uses-statement/test-uses-leaf-innertype2.yang
new file mode 100644 (file)
index 0000000..da72256
--- /dev/null
@@ -0,0 +1,12 @@
+module test-uses-leaf-innertype2 {
+    namespace "urn:test:uses:leaf:innertype2";
+    prefix uses-leaf;
+    revision 2017-08-09;
+    import test-uses-leaf-innertype2-base {
+      prefix "base";
+    }
+
+    container my-cont {
+      uses base:my-grp;
+    }
+}
\ No newline at end of file