MDSAL-361: Deal with restricted types in unions 57/76057/4
authorhan <han.jie@zte.com.cn>
Thu, 13 Sep 2018 09:56:27 +0000 (17:56 +0800)
committerRobert Varga <nite@hq.sk>
Wed, 3 Oct 2018 14:12:39 +0000 (14:12 +0000)
- Simply address the issue by adding a numeric suffix
  to member type name of the union.

Change-Id: Ie096f9e4795766ca8729daee6f54947ce90d964b
Signed-off-by: Jie Han <han.jie@zte.com.cn>
binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/AbstractTypeProvider.java
binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal361Test.java [new file with mode: 0644]
binding/mdsal-binding-generator-impl/src/test/resources/mdsal361.yang [new file with mode: 0644]

index 74a65c8c39e964c3823a626f327fbd91f15be600..50ba62a591ed9e4c1042aef22238f906cda0d294 100644 (file)
@@ -15,6 +15,8 @@ import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findP
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
 import com.google.common.io.BaseEncoding;
@@ -960,23 +962,25 @@ public abstract class AbstractTypeProvider implements TypeProvider {
         // Pattern string is the key, XSD regex is the value. The reason for this choice is that the pattern carries
         // also negation information and hence guarantees uniqueness.
         final Map<String, String> expressions = new HashMap<>();
+        final Map<TypeDefinition, String> propertyNames = resolveUnionMemberTypePropertyNames(unionTypes);
         for (TypeDefinition<?> unionType : unionTypes) {
-            final String unionTypeName = unionType.getQName().getLocalName();
+            final String propertyName = propertyNames.get(unionType);
 
             // If we have a base type we should follow the type definition backwards, except for identityrefs, as those
             // do not follow type encapsulation -- we use the general case for that.
             if (unionType.getBaseType() != null  && !(unionType instanceof IdentityrefTypeDefinition)) {
-                resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, expressions, parentNode);
+                resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, expressions, parentNode,
+                        propertyName);
             } else if (unionType instanceof UnionTypeDefinition) {
                 generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder,
                     (UnionTypeDefinition) unionType, parentNode));
             } else if (unionType instanceof EnumTypeDefinition) {
                 final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
-                        unionTypeName, unionGenTOBuilder);
-                updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
+                        propertyName, unionGenTOBuilder);
+                updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, propertyName);
             } else {
                 final Type javaType = javaTypeForSchemaDefinitionType(unionType, parentNode);
-                updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
+                updateUnionTypeAsProperty(unionGenTOBuilder, javaType, propertyName);
             }
         }
         addStringRegExAsConstant(unionGenTOBuilder, expressions);
@@ -986,6 +990,22 @@ public abstract class AbstractTypeProvider implements TypeProvider {
         return generatedTOBuilders;
     }
 
+    private Map<TypeDefinition, String> resolveUnionMemberTypePropertyNames(final List<TypeDefinition<?>> unionTypes) {
+        final BiMap<String, TypeDefinition> propertyNames = HashBiMap.create();
+        String propertyName;
+        Integer suffix = 0;
+        for (TypeDefinition<?> type : unionTypes) {
+            propertyName = type.getQName().getLocalName();
+            if (propertyNames.containsKey(propertyName)) {
+                propertyName = propertyName + (++suffix);
+            }
+
+            propertyNames.put(propertyName, type);
+        }
+
+        return propertyNames.inverse();
+    }
+
     /**
      * Wraps code which handles the case when union subtype is also of the type <code>UnionType</code>.
      *
@@ -1042,7 +1062,8 @@ public abstract class AbstractTypeProvider implements TypeProvider {
      *
      */
     private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
-            final TypeDefinition<?> unionSubtype, final Map<String, String> expressions, final SchemaNode parentNode) {
+            final TypeDefinition<?> unionSubtype, final Map<String, String> expressions, final SchemaNode parentNode,
+            final String propertyName) {
         final String unionTypeName = unionSubtype.getQName().getLocalName();
         final Type genTO = findGenTO(unionTypeName, unionSubtype);
         if (genTO != null) {
@@ -1055,7 +1076,7 @@ public abstract class AbstractTypeProvider implements TypeProvider {
             final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType,
                 parentNode, BindingGeneratorUtil.getRestrictions(unionSubtype));
             if (javaType != null) {
-                updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
+                updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, propertyName);
             }
         } else if (baseType instanceof LeafrefTypeDefinition) {
             final Type javaType = javaTypeForSchemaDefinitionType(baseType, parentNode);
diff --git a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal361Test.java b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal361Test.java
new file mode 100644 (file)
index 0000000..991ee1d
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.binding.generator.impl;
+
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.model.api.GeneratedProperty;
+import org.opendaylight.mdsal.binding.model.api.GeneratedType;
+import org.opendaylight.mdsal.binding.model.api.Type;
+import org.opendaylight.mdsal.binding.model.util.Types;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class Mdsal361Test {
+
+    @Test
+    public void mdsal361Test() {
+        final SchemaContext context = YangParserTestUtils.parseYangResource("/mdsal361.yang");
+
+        final List<Type> generateTypes = new BindingGeneratorImpl().generateTypes(context);
+        assertNotNull(generateTypes);
+        assertEquals(4, generateTypes.size());
+        for (final Type type : generateTypes) {
+            if (type.getName().equals("PceId")) {
+                final GeneratedType gt = (GeneratedType) type;
+                assertNotNull(gt);
+                assertEquals(2, gt.getProperties().size());
+            }
+
+            if (type.getName().equals("PceId2")) {
+                final GeneratedType gt = (GeneratedType) type;
+                assertNotNull(gt);
+                assertEquals(2, gt.getEnumerations().size());
+                assertEquals(2, gt.getProperties().size());
+            }
+        }
+    }
+}
diff --git a/binding/mdsal-binding-generator-impl/src/test/resources/mdsal361.yang b/binding/mdsal-binding-generator-impl/src/test/resources/mdsal361.yang
new file mode 100644 (file)
index 0000000..17d9dc9
--- /dev/null
@@ -0,0 +1,32 @@
+module mdsal361 {
+
+    namespace "yang:test:mdsal361";
+    prefix m;
+
+    revision 2018-09-13 {
+    }
+
+    typedef pce-id {
+        type union {
+            type binary {
+                length 4;
+            }
+            type binary {
+                length 16;
+            }
+        }
+    }
+
+    typedef pce-id-2 {
+        type union {
+            type enumeration {
+                enum a;
+            }
+
+            type enumeration {
+                enum b;
+            }
+        }
+    }
+
+}