Binding generator v2 - augments fix #2 02/59202/1
authorMartin Ciglan <martin.ciglan@pantheon.tech>
Fri, 16 Jun 2017 13:44:22 +0000 (15:44 +0200)
committerMartin Ciglan <martin.ciglan@pantheon.tech>
Tue, 20 Jun 2017 08:09:12 +0000 (08:09 +0000)
- handle uses-augment statements
for grouped augments by target path
- testing yang(s) included

- augmentations in groupings

TODO #3 Choice Cases

Change-Id: Ie670c03992bc41bb3e2f6efc1367f9bdf18da1b5
Signed-off-by: Martin Ciglan <martin.ciglan@pantheon.tech>
Signed-off-by: Jie Han <han.jie@zte.com.cn>
(cherry picked from commit c542a344f0a3b18625e49fe43d6c69cec29364fe)

binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AugmentToGenType.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/impl/ModuleContext.java
binding2/mdsal-binding2-generator-impl/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AugmentToGenTypeTest.java
binding2/mdsal-binding2-generator-impl/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/impl/Bug8542Test.java
binding2/mdsal-binding2-generator-impl/src/test/resources/augment-group/test-augment-uses-grouping.yang [new file with mode: 0644]
binding2/mdsal-binding2-generator-impl/src/test/resources/augment-group/test-augment-uses.yang [new file with mode: 0644]
binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/BindingGeneratorUtil.java
binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/GeneratedTypeBuilderImpl.java
binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding/javav2/java/api/generator/builderTemplate.scala.txt

index 7fe70dabbb3c7c8d2b157b89fc146ff505f1ebcd..2be4fd43a7aa608d98efb4f5ab46e1de8d5fa3c4 100644 (file)
@@ -110,6 +110,12 @@ final class AugmentToGenType {
         for (Entry<SchemaPath, List<AugmentationSchema>> schemaPathAugmentListEntry : augmentationsGrouped.entrySet()) {
             resultCtx = augmentationToGenTypes(basePackageName, schemaPathAugmentListEntry, module, schemaContext,
                     verboseClassComments, resultCtx, genTypeBuilders, typeProvider);
+
+            for (AugmentationSchema augSchema : schemaPathAugmentListEntry.getValue()) {
+                GenHelperUtil.processUsesAugments(schemaContext, augSchema, module, genCtx,
+                        genTypeBuilders, verboseClassComments, typeProvider);
+            }
+
         }
 
         return resultCtx;
@@ -164,19 +170,17 @@ final class AugmentToGenType {
      *             if augment target path is null
      * @return generated context
      */
-    private static Map<Module, ModuleContext> augmentationToGenTypes(final String augmentPackageName,
+    private static Map<Module, ModuleContext> augmentationToGenTypes(final String basePackageName,
             final Entry<SchemaPath, List<AugmentationSchema>> schemaPathAugmentListEntry, final Module module,
             final SchemaContext schemaContext, final boolean verboseClassComments,
             Map<Module, ModuleContext> genCtx, Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
             final TypeProvider typeProvider) {
 
         final SchemaPath targetPath = schemaPathAugmentListEntry.getKey();
-        Preconditions.checkArgument(augmentPackageName != null, "Package Name cannot be NULL.");
+        Preconditions.checkArgument(basePackageName != null, "Package Name cannot be NULL.");
         Preconditions.checkState(targetPath != null,
                 "Augmentation Schema does not contain Target Path (Target Path is NULL).");
 
-        //TODO: implement uses-augment scenario
-
         SchemaNode targetSchemaNode;
 
         targetSchemaNode = SchemaContextUtil.findDataSchemaNode(schemaContext, targetPath);
@@ -194,7 +198,7 @@ final class AugmentToGenType {
             throw new IllegalArgumentException("augment target not found: " + targetPath);
         }
 
-        //TODO: loose this assignment afterwards
+        //TODO: loose this assignment afterwards #2 done
         Map<Module, ModuleContext> generatedCtx = genCtx;
 
         GeneratedTypeBuilder targetTypeBuilder = GenHelperUtil.findChildNodeByPath(targetSchemaNode.getPath(),
@@ -206,22 +210,73 @@ final class AugmentToGenType {
             throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
         }
 
+        final String augmentNamespacePackageName =
+                BindingGeneratorUtil.packageNameForAugmentedGeneratedType(basePackageName, targetPath);
+
         if (!(targetSchemaNode instanceof ChoiceSchemaNode)) {
-            generatedCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, augmentPackageName,
+            generatedCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, augmentNamespacePackageName,
                     targetTypeBuilder.toInstance(), schemaPathAugmentListEntry.getValue(), genTypeBuilders, generatedCtx,
                     schemaContext, verboseClassComments, typeProvider);
         } else {
-            //TODO: implement augmented choice cases scenario
+            //TODO: #3 implement augmented choice cases scenario
         }
         return generatedCtx;
     }
 
     static Map<Module, ModuleContext> usesAugmentationToGenTypes(final SchemaContext schemaContext,
-           final String augmentPackageName, final AugmentationSchema augSchema, final Module module,
+           final String augmentPackageName, final List<AugmentationSchema> schemaPathAugmentListEntry, final Module module,
            final UsesNode usesNode, final DataNodeContainer usesNodeParent, Map<Module, ModuleContext> genCtx,
            Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final boolean verboseClassComments,
            final TypeProvider typeProvider) {
 
+        Preconditions.checkArgument(augmentPackageName != null, "Package Name cannot be NULL.");
+
+        final SchemaPath targetPath = schemaPathAugmentListEntry.get(0).getTargetPath();
+        final SchemaNode targetSchemaNode = findOriginalTargetFromGrouping(schemaContext, targetPath, usesNode);
+        if (targetSchemaNode == null) {
+            throw new IllegalArgumentException("augment target not found: " + targetPath);
+        }
+
+        GeneratedTypeBuilder targetTypeBuilder = GenHelperUtil.findChildNodeByPath(targetSchemaNode.getPath(),
+                genCtx);
+        if (targetTypeBuilder == null) {
+            targetTypeBuilder = GenHelperUtil.findCaseByPath(targetSchemaNode.getPath(), genCtx);
+        }
+        if (targetTypeBuilder == null) {
+            throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
+        }
+
+        if (!(targetSchemaNode instanceof ChoiceSchemaNode)) {
+            String packageName = augmentPackageName;
+            if (usesNodeParent instanceof SchemaNode) {
+                packageName = BindingGeneratorUtil.packageNameForAugmentedGeneratedType(augmentPackageName,
+                        ((SchemaNode) usesNodeParent).getPath());
+            } else if (usesNodeParent instanceof AugmentationSchema) {
+                Type parentTypeBuilder = genCtx.get(module).getTargetToAugmentation()
+                        .get(((AugmentationSchema) usesNodeParent).getTargetPath());
+                packageName = parentTypeBuilder.getFullyQualifiedName();
+            }
+            genCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, packageName,
+                    targetTypeBuilder.toInstance(), schemaPathAugmentListEntry, genTypeBuilders, genCtx,
+                    schemaContext, verboseClassComments, typeProvider);
+            return genCtx;
+        } else {
+            genCtx = generateTypesFromAugmentedChoiceCases(schemaContext, module, augmentPackageName,
+                    targetTypeBuilder.toInstance(), (ChoiceSchemaNode) targetSchemaNode,
+                    schemaPathAugmentListEntry.get(0).getChildNodes(),
+                    usesNodeParent, genCtx, verboseClassComments, genTypeBuilders, typeProvider);
+            return genCtx;
+        }
+    }
+
+    //TODO: delete this method eventually when uses-augments & augmented choice cases are implemented
+    @Deprecated
+    public static Map<Module, ModuleContext> usesAugmentationToGenTypes(final SchemaContext schemaContext, final String
+            augmentPackageName, final AugmentationSchema augSchema, final Module module, final UsesNode usesNode, final DataNodeContainer
+                                                                                usesNodeParent, Map<Module, ModuleContext> genCtx,
+                                                                        Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+                                                                        final boolean verboseClassComments, final TypeProvider typeProvider) {
+
         Preconditions.checkArgument(augmentPackageName != null, "Package Name cannot be NULL.");
         Preconditions.checkArgument(augSchema != null, "Augmentation Schema cannot be NULL.");
         Preconditions.checkState(augSchema.getTargetPath() != null,
@@ -248,9 +303,9 @@ final class AugmentToGenType {
                 packageName = BindingGeneratorUtil.packageNameForAugmentedGeneratedType(augmentPackageName,
                         ((SchemaNode) usesNodeParent).getPath());
             } else if (usesNodeParent instanceof AugmentationSchema) {
-                Type parentTypeBuiler = genCtx.get(module).getTypeToAugmentation().inverse().get(usesNodeParent);
+                Type parentTypeBuilder = genCtx.get(module).getTypeToAugmentation().inverse().get(usesNodeParent);
                 packageName = BindingGeneratorUtil.packageNameForAugmentedGeneratedType(
-                        parentTypeBuiler.getPackageName(), (AugmentationSchema)usesNodeParent);
+                        parentTypeBuilder.getPackageName(), (AugmentationSchema)usesNodeParent);
             }
             genCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
                     targetTypeBuilder.toInstance(), augSchema, genTypeBuilders, genCtx, schemaContext,
index 25e3aa78e8fe5563db22a612073fcbcfe0a152bf..db1ea3c422c15efadc64ba875dfa09d2414fa428 100644 (file)
@@ -37,6 +37,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
+
 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes;
@@ -255,11 +257,16 @@ final class GenHelperUtil {
                         final boolean verboseClassComments, final TypeProvider typeProvider) {
         final String basePackageName = BindingMapping.getRootPackageName(module);
         for (final UsesNode usesNode : node.getUses()) {
-            for (final AugmentationSchema augment : usesNode.getAugmentations()) {
-                genCtx = AugmentToGenType.usesAugmentationToGenTypes(schemaContext, basePackageName, augment, module,
+            Map<SchemaPath, List<AugmentationSchema>> augmentationsGrouped =
+                    usesNode.getAugmentations().stream().collect(Collectors.groupingBy(AugmentationSchema::getTargetPath));
+            for (Map.Entry<SchemaPath, List<AugmentationSchema>> schemaPathAugmentListEntry : augmentationsGrouped.entrySet()) {
+                genCtx = AugmentToGenType.usesAugmentationToGenTypes(schemaContext, basePackageName,
+                        schemaPathAugmentListEntry.getValue(), module,
                         usesNode, node, genCtx, genTypeBuilders, verboseClassComments, typeProvider);
-                genCtx = processUsesAugments(schemaContext, augment, module, genCtx, genTypeBuilders,
-                        verboseClassComments, typeProvider);
+                for (AugmentationSchema augSchema : schemaPathAugmentListEntry.getValue()) {
+                    genCtx = processUsesAugments(schemaContext, augSchema, module, genCtx, genTypeBuilders,
+                            verboseClassComments, typeProvider);
+                }
             }
         }
         return genCtx;
@@ -293,11 +300,8 @@ final class GenHelperUtil {
         //pick augmentation grouped by augmentation target, there is always at least one
         final AugmentationSchema augSchema = schemaPathAugmentListEntry.get(0);
 
-        final String augmentNamespacePackageName = BindingGeneratorUtil.packageNameForGeneratedType(augmentPackageName,
-                augSchema.getTargetPath(), BindingNamespaceType.Data);
-
         Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.computeIfAbsent(
-                augmentNamespacePackageName, k -> new HashMap<>());
+                augmentPackageName, k -> new HashMap<>());
 
         //this requires valid semantics in YANG model
         String augIdentifier = null;
@@ -310,7 +314,8 @@ final class GenHelperUtil {
             augIdentifier = augGenTypeName(augmentBuilders, targetTypeRef.getName());
         }
 
-        GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentNamespacePackageName, augIdentifier);
+        GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augIdentifier,
+                false, true);
 
         augTypeBuilder.addImplementsType(BindingTypes.TREE_NODE);
         augTypeBuilder.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, augTypeBuilder));
@@ -321,7 +326,7 @@ final class GenHelperUtil {
         for (AugmentationSchema aug : schemaPathAugmentListEntry) {
             //apply all uses
             addImplementedInterfaceFromUses(aug, augTypeBuilder, genCtx);
-            augSchemaNodeToMethods(module, augmentNamespacePackageName, augTypeBuilder, augTypeBuilder, aug.getChildNodes(),
+            augSchemaNodeToMethods(module, augmentPackageName, augTypeBuilder, augTypeBuilder, aug.getChildNodes(),
                genCtx, schemaContext, verboseClassComments, typeProvider, genTypeBuilders);
         }
 
@@ -329,6 +334,7 @@ final class GenHelperUtil {
 
         if(!augSchema.getChildNodes().isEmpty()) {
             genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
+            genCtx.get(module).addTargetToAugmentation(augTypeBuilder, augSchema.getTargetPath());
         }
         genCtx.get(module).addAugmentType(augTypeBuilder);
         return genCtx;
index 4a80b28c80db90a6bcf410617319bad0aa9842f1..b240b1183b071b0487d18d6a4f7939bce5bf97e6 100644 (file)
@@ -50,11 +50,13 @@ public final class ModuleContext {
     private final Set<GeneratedTypeBuilder> topLevelNodes = new HashSet<>();
     private final List<GeneratedTypeBuilder> augmentations = new ArrayList<>();
     private final BiMap<Type,AugmentationSchema> typeToAugmentation = HashBiMap.create();
+    private final BiMap<SchemaPath,Type> targetToAugmentation = HashBiMap.create();
     private final Map<Type,Object> typeToSchema = new HashMap<>();
     private final Multimap<Type, Type> choiceToCases = HashMultimap.create();
     private final BiMap<Type,ChoiceCaseNode> caseTypeToSchema = HashBiMap.create();
     private final Map<SchemaPath, Type> innerTypes = new HashMap<>();
 
+
     List<Type> getGeneratedTypes() {
         final List<Type> result = new ArrayList<>();
 
@@ -163,11 +165,19 @@ public final class ModuleContext {
         return Maps.unmodifiableBiMap(this.typeToAugmentation);
     }
 
+    public BiMap<SchemaPath, Type> getTargetToAugmentation() {
+        return Maps.unmodifiableBiMap(this.targetToAugmentation);
+    }
+
     public void addTypeToAugmentation(final GeneratedTypeBuilder builder, final AugmentationSchema schema) {
         this.typeToAugmentation.put(builder, schema);
         this.typeToSchema.put(builder, schema);
     }
 
+    public void addTargetToAugmentation(final GeneratedTypeBuilder builder, final SchemaPath augmentTarget) {
+        this.targetToAugmentation.put(augmentTarget, builder);
+    }
+
     public void addChoiceToCaseMapping(final Type choiceType, final Type caseType, final ChoiceCaseNode schema) {
         this.choiceToCases.put(choiceType, caseType);
         this.caseTypeToSchema.put(caseType, schema);
index 1ddeb46a04cdec3e5652d51f7c5f61556f93e878..77f5e298df2fcd143a5cb1a25cbe68026feaef0e 100644 (file)
@@ -655,7 +655,7 @@ public class AugmentToGenTypeTest {
     @Test
     public void usesAugmentationToGenTypesNullPckgNameTest() throws Exception {
         try {
-            AugmentToGenType.usesAugmentationToGenTypes(null, null, null, null, null, null, null, null, false, null);
+            AugmentToGenType.usesAugmentationToGenTypes(null, null, (AugmentationSchema) null, null, null, null, null, null, false, null);
         } catch (final Exception e) {
             assertNotNull(e);
             assertTrue(e instanceof IllegalArgumentException);
@@ -666,7 +666,7 @@ public class AugmentToGenTypeTest {
     @Test
     public void usesAugmentationToGenTypesNullAugSchemaNodeTest() throws Exception {
         try {
-            AugmentToGenType.usesAugmentationToGenTypes(null, "", null, null, null, null, null, null, false, null);
+            AugmentToGenType.usesAugmentationToGenTypes(null, "", (AugmentationSchema) null, null, null, null, null, null, false, null);
         } catch (final Exception e) {
             assertNotNull(e);
             assertTrue(e instanceof IllegalArgumentException);
index 1257661053216b46718fb5f0b46228a87d24d7db..66b04e6f8650242fb87294bdd27a846abd6ac23b 100644 (file)
@@ -28,13 +28,13 @@ public class Bug8542Test {
         assertTrue(!generateTypes.isEmpty());
         for (final Type type : generateTypes) {
             if (type.getName().equals("A11")) {
-                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.d",
+                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.data.d",
                         type.getPackageName());
             } else if (type.getName().equals("B11")) {
-                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.d.a1",
+                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.data.d.a11",
                         type.getPackageName());
             } else if (type.getName().equals("C11")) {
-                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.d.a1.b1",
+                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.data.d.a11.b11",
                         type.getPackageName());
             }
         }
diff --git a/binding2/mdsal-binding2-generator-impl/src/test/resources/augment-group/test-augment-uses-grouping.yang b/binding2/mdsal-binding2-generator-impl/src/test/resources/augment-group/test-augment-uses-grouping.yang
new file mode 100644 (file)
index 0000000..2bee56a
--- /dev/null
@@ -0,0 +1,38 @@
+module augment-test-uses-grouping {
+    prefix "foo";
+    namespace "org.test.augment.uses.grouping";
+
+    container foo1 {
+        leaf my-leaf {
+            type string;
+        }
+    }
+
+    augment /foo:foo1 {
+        uses grp {
+           augment my-cont {
+              leaf my-uses-grp-leaf {
+                  type string;
+              }
+           }
+        }
+
+        leaf bar {
+            type string;
+        }
+    }
+
+    augment /foo:foo1 {
+        leaf baz {
+            type string;
+        }
+    }
+
+    grouping grp {
+        container my-cont {
+            leaf my-grp-leaf {
+              type string;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-generator-impl/src/test/resources/augment-group/test-augment-uses.yang b/binding2/mdsal-binding2-generator-impl/src/test/resources/augment-group/test-augment-uses.yang
new file mode 100644 (file)
index 0000000..fec47e0
--- /dev/null
@@ -0,0 +1,29 @@
+module augment-test-uses {
+    prefix "foo";
+    namespace "org.test.augment.uses";
+
+    container foo1 {
+        leaf my-leaf {
+            type string;
+        }
+    }
+
+    augment /foo:foo1 {
+        uses grp;
+        leaf bar {
+            type string;
+        }
+    }
+
+    augment /foo:foo1 {
+        leaf baz {
+            type string;
+        }
+    }
+
+    grouping grp {
+        leaf my-grp-leaf {
+            type string;
+        }
+    }
+}
\ No newline at end of file
index 62636ac49f19ad050442f449d1c4264db4358ef8..23493939722b4e36de7c065e72df58b4c0e6bde7 100644 (file)
@@ -371,7 +371,7 @@ public final class BindingGeneratorUtil {
             return basePackageName;
         }
 
-        return generateNormalizedPackageName(basePackageName, pathFromRoot, size, null);
+        return generateNormalizedPackageName(basePackageName, pathFromRoot, size, BindingNamespaceType.Data);
     }
 
     /**
index ae12dab54502b0bb443d677f95e4bb7e5c4d2150..9b0f0a5c16cc1b3a895fd925202e233da46b9a3d 100644 (file)
@@ -29,6 +29,13 @@ public final class GeneratedTypeBuilderImpl extends AbstractGeneratedTypeBuilder
         setAbstract(true);
     }
 
+    public GeneratedTypeBuilderImpl(final String packageName, final String name,
+                                    final boolean isPkNameNormalized,
+                                    final boolean isTypeNormalized) {
+        super(packageName, name, isPkNameNormalized, isTypeNormalized);
+        setAbstract(true);
+    }
+
     @Override
     public GeneratedType toInstance() {
         return new GeneratedTypeImpl(this);
index 25af90df30edc67832ffac05f4bfa10c67898c94..6d0607ebbf1b65dc3871c71afb166834ae362cc7 100644 (file)
@@ -131,7 +131,7 @@ public class @{genType.getName}Builder implements @{getSimpleNameForBuilder} <@{
     @if(genType.isInstanceOf[GeneratedType] && !genType.isInstanceOf[GeneratedTransferObject]) {
         @if(hasImplementsFromUses(genType.asInstanceOf[GeneratedType])) {
             /**
-             *Set fields from given grouping argument. Valid argument is instance of one of following types:
+             * Set fields from given grouping argument. Valid argument is instance of one of following types:
              * <ul>
              @for(impl <- getAllIfcs(genType.asInstanceOf[GeneratedType])) {
              * <li>@{impl.getFullyQualifiedName}</li>
@@ -147,8 +147,8 @@ public class @{genType.getName}Builder implements @{getSimpleNameForBuilder} <@{
                 @for(impl <- getAllIfcs(genType.asInstanceOf[GeneratedType])) {
                     @if(impl.isInstanceOf[GeneratedType] && !impl.asInstanceOf[GeneratedType].getMethodDefinitions.isEmpty) {
                         if (arg instanceof @{impl.asInstanceOf[GeneratedType].getFullyQualifiedName}) {
-                            @if(!impl.isInstanceOf[GeneratedTransferObject]) {
-                                @for(getter <- genType.asInstanceOf[GeneratedType].getMethodDefinitions) {
+                            @if(impl.isInstanceOf[GeneratedType] && !impl.isInstanceOf[GeneratedTransferObject]) {
+                                @for(getter <- impl.asInstanceOf[GeneratedType].getMethodDefinitions) {
                                     this._@{propertyNameFromGetter(getter)} = ((@{impl.asInstanceOf[GeneratedType].getFullyQualifiedName})arg).@{getter.getName}();
                                 }
                             }