Test for nested union in typedef and leaf added. 62/962/2
authorJozef Gloncak <jgloncak@cisco.com>
Thu, 22 Aug 2013 12:46:24 +0000 (14:46 +0200)
committerMartin Vitez <mvitez@cisco.com>
Thu, 22 Aug 2013 14:30:06 +0000 (16:30 +0200)
- BitAndUnionTOEnclosingTest class was rewritten
- MethodSignaturePattern renamed to NameTypePattern
- bit_and_union_in_leaf.yang was changed and renamed to bit_and_union.yang

Change-Id: Ib5b158d90ab2f2f5e5b121484cb7aad07b271e46
Signed-off-by: Jozef Gloncak <jgloncak@cisco.com>
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/BitAndUnionTOEnclosingTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/NameTypePattern.java [moved from code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/MethodSignaturePattern.java with 57% similarity]
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/SupportTestUtil.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/UsesTest.java
code-generator/binding-generator-impl/src/test/resources/bit_and_union.yang [moved from code-generator/binding-generator-impl/src/test/resources/bit_and_union_in_leaf.yang with 69% similarity]

index c87c47e6556b7c0ddc981cf7fbb5193b9594dd1e..e7f81b2af55d0b8ae33befc21104564d8495e93f 100644 (file)
@@ -20,6 +20,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.commons.lang.StringEscapeUtils;
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
 import org.opendaylight.yangtools.binding.generator.util.TypeConstants;
 import org.opendaylight.yangtools.binding.generator.util.Types;
 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.EnumerationBuilderImpl;
@@ -84,7 +85,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             if <code>schemaContext</code> equal null.
      */
     public TypeProviderImpl(final SchemaContext schemaContext) {
-        Preconditions.checkArgument(schemaContext != null,"Schema Context cannot be null!");
+        Preconditions.checkArgument(schemaContext != null, "Schema Context cannot be null!");
 
         this.schemaContext = schemaContext;
         this.genTypeDefsContextMap = new HashMap<>();
@@ -107,9 +108,10 @@ public final class TypeProviderImpl implements TypeProvider {
      * 
      */
     public void putReferencedType(final SchemaPath refTypePath, final Type refType) {
-        Preconditions.checkArgument(refTypePath != null,"Path reference of Enumeration Type Definition cannot be NULL!");
+        Preconditions.checkArgument(refTypePath != null,
+                "Path reference of Enumeration Type Definition cannot be NULL!");
 
-        Preconditions.checkArgument(refType != null,"Reference to Enumeration Type cannot be NULL!");
+        Preconditions.checkArgument(refType != null, "Reference to Enumeration Type cannot be NULL!");
         referencedTypes.put(refTypePath, refType);
     }
 
@@ -144,12 +146,13 @@ public final class TypeProviderImpl implements TypeProvider {
     @Override
     public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition) {
         Type returnType = null;
-        Preconditions.checkArgument(typeDefinition != null,"Type Definition cannot be NULL!");
+        Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
         if (typeDefinition.getQName() == null) {
             throw new IllegalArgumentException(
                     "Type Definition cannot have non specified QName (QName cannot be NULL!)");
         }
-        Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,"Type Definitions Local Name cannot be NULL!");
+        Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
+                "Type Definitions Local Name cannot be NULL!");
 
         if (typeDefinition instanceof ExtendedType) {
             returnType = javaTypeForExtendedType(typeDefinition);
@@ -221,6 +224,12 @@ public final class TypeProviderImpl implements TypeProvider {
             }
         }
         return returnType;
+        // TODO: add throw exception when we will be able to resolve ALL yang
+        // types!
+        // if (returnType == null) {
+        // throw new IllegalArgumentException("Type Provider can't resolve " +
+        // "type for specified Type Definition " + typedefName);
+        // }
     }
 
     /**
@@ -247,7 +256,7 @@ public final class TypeProviderImpl implements TypeProvider {
                 identity = id;
             }
         }
-        Preconditions.checkArgument(identity != null,"Target identity '" + baseIdQName + "' do not exists");
+        Preconditions.checkArgument(identity != null, "Target identity '" + baseIdQName + "' do not exists");
 
         final String basePackageName = moduleNamespaceToPackageName(module);
         final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
@@ -275,12 +284,13 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition) {
         Type returnType = null;
-        Preconditions.checkArgument(typeDefinition != null,"Type Definition cannot be NULL!");
+        Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
         if (typeDefinition.getQName() == null) {
             throw new IllegalArgumentException(
                     "Type Definition cannot have non specified QName (QName cannot be NULL!)");
         }
-        Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,"Type Definitions Local Name cannot be NULL!");
+        Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
+                "Type Definitions Local Name cannot be NULL!");
 
         final String typedefName = typeDefinition.getQName().getLocalName();
         if (typeDefinition instanceof ExtendedType) {
@@ -311,7 +321,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             if <code>extendTypeDef</code> equal null
      */
     private TypeDefinition<?> baseTypeDefForExtendedType(final TypeDefinition<?> extendTypeDef) {
-        Preconditions.checkArgument(extendTypeDef != null,"Type Definiition reference cannot be NULL!");
+        Preconditions.checkArgument(extendTypeDef != null, "Type Definiition reference cannot be NULL!");
         final TypeDefinition<?> baseTypeDef = extendTypeDef.getBaseType();
         if (baseTypeDef instanceof ExtendedType) {
             return baseTypeDefForExtendedType(baseTypeDef);
@@ -340,9 +350,10 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) {
         Type returnType = null;
-        Preconditions.checkArgument(leafrefType != null,"Leafref Type Definition reference cannot be NULL!");
+        Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
 
-        Preconditions.checkArgument(leafrefType.getPathStatement() != null,"The Path Statement for Leafref Type Definition cannot be NULL!");
+        Preconditions.checkArgument(leafrefType.getPathStatement() != null,
+                "The Path Statement for Leafref Type Definition cannot be NULL!");
 
         final RevisionAwareXPath xpath = leafrefType.getPathStatement();
         final String strXPath = xpath.toString();
@@ -440,10 +451,12 @@ public final class TypeProviderImpl implements TypeProvider {
      *             </ul>
      */
     private Enumeration provideTypeForEnum(final EnumTypeDefinition enumTypeDef, final String enumName) {
-        Preconditions.checkArgument(enumTypeDef != null,"EnumTypeDefinition reference cannot be NULL!");
-        Preconditions.checkArgument(enumTypeDef.getValues() != null,"EnumTypeDefinition MUST contain at least ONE value definition!");
-        Preconditions.checkArgument(enumTypeDef.getQName() != null,"EnumTypeDefinition MUST contain NON-NULL QName!");
-        Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,"Local Name in EnumTypeDefinition QName cannot be NULL!");
+        Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
+        Preconditions.checkArgument(enumTypeDef.getValues() != null,
+                "EnumTypeDefinition MUST contain at least ONE value definition!");
+        Preconditions.checkArgument(enumTypeDef.getQName() != null, "EnumTypeDefinition MUST contain NON-NULL QName!");
+        Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,
+                "Local Name in EnumTypeDefinition QName cannot be NULL!");
 
         final String enumerationName = parseToClassName(enumName);
 
@@ -480,11 +493,13 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     private Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, final String enumName,
             final GeneratedTypeBuilder typeBuilder) {
-        Preconditions.checkArgument(enumTypeDef != null,"EnumTypeDefinition reference cannot be NULL!");
-        Preconditions.checkArgument(enumTypeDef.getValues() != null,"EnumTypeDefinition MUST contain at least ONE value definition!");
-        Preconditions.checkArgument(enumTypeDef.getQName() != null,"EnumTypeDefinition MUST contain NON-NULL QName!");
-        Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,"Local Name in EnumTypeDefinition QName cannot be NULL!");
-        Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder reference cannot be NULL!");
+        Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
+        Preconditions.checkArgument(enumTypeDef.getValues() != null,
+                "EnumTypeDefinition MUST contain at least ONE value definition!");
+        Preconditions.checkArgument(enumTypeDef.getQName() != null, "EnumTypeDefinition MUST contain NON-NULL QName!");
+        Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,
+                "Local Name in EnumTypeDefinition QName cannot be NULL!");
+        Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!");
 
         final String enumerationName = parseToClassName(enumName);
 
@@ -530,7 +545,7 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     private void resolveTypeDefsFromContext() {
         final Set<Module> modules = schemaContext.getModules();
-        Preconditions.checkArgument(modules != null,"Sef of Modules cannot be NULL!");
+        Preconditions.checkArgument(modules != null, "Sef of Modules cannot be NULL!");
         final Module[] modulesArray = new Module[modules.size()];
         int i = 0;
         for (Module modul : modules) {
@@ -703,8 +718,8 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
             final TypeDefinition<?> typedef, final String typeDefName) {
-        Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL!");
-        Preconditions.checkArgument(typedef != null,"Type Definition cannot be NULL!");
+        Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
+        Preconditions.checkArgument(typedef != null, "Type Definition cannot be NULL!");
         if (typedef.getQName() == null) {
             throw new IllegalArgumentException(
                     "Type Definition cannot have non specified QName (QName cannot be NULL!)");
@@ -785,7 +800,9 @@ public final class TypeProviderImpl implements TypeProvider {
         final List<GeneratedTOBuilder> subUnionGenTOBUilders = provideGeneratedTOBuildersForUnionTypeDef(
                 basePackageName, unionSubtype, newTOBuilderName);
 
-        GeneratedPropertyBuilder propertyBuilder = parentUnionGenTOBuilder.addProperty(newTOBuilderName);
+        final GeneratedPropertyBuilder propertyBuilder;
+        propertyBuilder = parentUnionGenTOBuilder.addProperty(BindingGeneratorUtil
+                .parseToValidParamName(newTOBuilderName));
         propertyBuilder.setReturnType(subUnionGenTOBUilders.get(0));
         parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
         parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
@@ -949,8 +966,8 @@ public final class TypeProviderImpl implements TypeProvider {
     public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName,
             final TypeDefinition<?> typeDef, String typeDefName) {
 
-        Preconditions.checkArgument(typeDef != null,"typeDef cannot be NULL!");
-        Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL!");
+        Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");
+        Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
 
         if (typeDef instanceof BitsTypeDefinition) {
             BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
@@ -989,7 +1006,7 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     private List<String> resolveRegExpressionsFromTypedef(ExtendedType typedef) {
         final List<String> regExps = new ArrayList<String>();
-        Preconditions.checkArgument(typedef != null,"typedef can't be null");
+        Preconditions.checkArgument(typedef != null, "typedef can't be null");
         final TypeDefinition<?> strTypeDef = baseTypeDefForExtendedType(typedef);
         if (strTypeDef instanceof StringType) {
             final List<PatternConstraint> patternConstraints = typedef.getPatterns();
@@ -1062,9 +1079,9 @@ public final class TypeProviderImpl implements TypeProvider {
     private GeneratedTransferObject provideGeneratedTOFromExtendedType(final ExtendedType innerExtendedType,
             final String basePackageName, final String typedefName) {
 
-        Preconditions.checkArgument(innerExtendedType != null,"Extended type cannot be NULL!");
-        Preconditions.checkArgument(basePackageName != null,"String with base package name cannot be NULL!");
-        Preconditions.checkArgument(typedefName != null,"String with type definition name cannot be NULL!");
+        Preconditions.checkArgument(innerExtendedType != null, "Extended type cannot be NULL!");
+        Preconditions.checkArgument(basePackageName != null, "String with base package name cannot be NULL!");
+        Preconditions.checkArgument(typedefName != null, "String with type definition name cannot be NULL!");
 
         final String classTypedefName = parseToClassName(typedefName);
         final String innerTypeDef = innerExtendedType.getQName().getLocalName();
@@ -1134,7 +1151,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *         definition to the base type
      */
     private int getTypeDefinitionDepth(final TypeDefinition<?> typeDefinition) {
-        Preconditions.checkArgument(typeDefinition != null,"Type definition can't be null");
+        Preconditions.checkArgument(typeDefinition != null, "Type definition can't be null");
         int depth = 1;
         TypeDefinition<?> baseType = typeDefinition.getBaseType();
 
index 5545ce63ef866bab53ea8bd4c7e034fba5b63514..42e30aaedab0552f67f62adbeec7e4c694fd29b3 100644 (file)
@@ -9,6 +9,9 @@ package org.opendaylight.yangtools.sal.binding.generator.impl;
 
 import static org.junit.Assert.*;
 
+import static org.opendaylight.yangtools.sal.binding.generator.impl.SupportTestUtil.containsMethods;
+import static org.opendaylight.yangtools.sal.binding.generator.impl.SupportTestUtil.containsAttributes;
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
@@ -29,37 +32,173 @@ import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 public class BitAndUnionTOEnclosingTest {
 
     private final static List<File> testModels = new ArrayList<File>();
+    private static List<Type> genTypes = null;
+    private static GeneratedType parentContainer = null;
+
+    public static void parseResources() {
+        final YangModelParser parser = new YangParserImpl();
+        final Set<Module> modules = parser.parseYangModels(testModels);
+        final SchemaContext context = parser.resolveSchemaContext(modules);
+
+        assertNotNull(context);
+        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        genTypes = bindingGen.generateTypes(context);
+
+        for (Type type : genTypes) {
+            if (type instanceof GeneratedType) {
+                GeneratedType genType = (GeneratedType) type;
+                if (genType.getName().equals("ParentContainer") && !(genType instanceof GeneratedTransferObject)) {
+                    parentContainer = genType;
+                }
+            }
+        }
+    }
 
     @BeforeClass
     public static void loadTestResources() {
-        final File listModelFile = new File(ExtendedTypedefTest.class.getResource("/bit_and_union_in_leaf.yang")
-                .getPath());
+        final File listModelFile = new File(ExtendedTypedefTest.class.getResource("/bit_and_union.yang").getPath());
         testModels.add(listModelFile);
+        parseResources();
     }
 
     @Test
-    public void bitAndUnionEnclosingTest() {
-        final YangModelParser parser = new YangParserImpl();
-        final Set<Module> modules = parser.parseYangModels(testModels);
-        final SchemaContext context = parser.resolveSchemaContext(modules);
+    public void testNestedTypesInLeaf() {
+        GeneratedTransferObject lfLeaf = null;
+        int lfLeafCounter = 0;
+        GeneratedTransferObject lf1Leaf = null;
+        int lf1LeafCounter = 0;
+        GeneratedTransferObject lf2Leaf = null;
+        int lf2LeafCounter = 0;
+        List<GeneratedType> enclosedTypes = parentContainer.getEnclosedTypes();
+        for (GeneratedType genType : enclosedTypes) {
+            if (genType instanceof GeneratedTransferObject) {
+                if (genType.getName().equals("Lf")) {
+                    lfLeaf = (GeneratedTransferObject) genType;
+                    lfLeafCounter++;
+                } else if (genType.getName().equals("Lf1")) {
+                    lf1Leaf = (GeneratedTransferObject) genType;
+                    lf1LeafCounter++;
+                } else if (genType.getName().equals("Lf2")) {
+                    lf2Leaf = (GeneratedTransferObject) genType;
+                    lf2LeafCounter++;
+                }
 
-        assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
-        final List<Type> genTypes = bindingGen.generateTypes(context);
+            }
+        }
+
+        // nested types in leaf, contains Lf?
+        assertNotNull("Lf TO wasn't found.", lfLeaf);
+        assertEquals("Lf TO has incorrect number of occurences.", 1, lfLeafCounter);
+        assertEquals("Lf has incorrect package name.",
+                "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626.ParentContainer",
+                lfLeaf.getPackageName());
+
+        assertEquals("Lf generated TO has incorrect number of properties", 2, lfLeaf.getProperties().size());
+        containsAttributes(lfLeaf, true, true, true, new NameTypePattern("string", "String"));
+        containsAttributes(lfLeaf, true, false, true, new NameTypePattern("lf1", "Lf1"));
+
+        // nested types in leaf, contains Lf1?
+        assertNotNull("Lf1 TO wasn't found.", lf1Leaf);
+        assertEquals("Lf1 TO has incorrect number of occurences.", 1, lf1LeafCounter);
+        assertEquals("Lf1 has incorrect package name.",
+                "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626.ParentContainer",
+                lf1Leaf.getPackageName());
+
+        assertEquals("Lf generated TO has incorrect number of properties", 4, lf1Leaf.getProperties().size());
+        containsAttributes(lf1Leaf, true, true, true, new NameTypePattern("uint32", "Long"));
+        containsAttributes(lf1Leaf, true, true, true, new NameTypePattern("int8", "Byte"));
+        containsAttributes(lf1Leaf, true, true, true, new NameTypePattern("string", "String"));
+        containsAttributes(lf1Leaf, true, false, true, new NameTypePattern("lf2", "Lf2"));
+
+        // nested types in leaf, contains Lf2?
+        assertNotNull("Lf2 TO wasn't found.", lf2Leaf);
+        assertEquals("Lf2 TO has incorrect number of occurences.", 1, lf2LeafCounter);
+        assertEquals("Lf2 has incorrect package name.",
+                "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626.ParentContainer",
+                lf2Leaf.getPackageName());
+
+        assertEquals("Lf generated TO has incorrect number of properties", 2, lf2Leaf.getProperties().size());
+        containsAttributes(lf2Leaf, true, true, true, new NameTypePattern("string", "String"));
+        containsAttributes(lf2Leaf, true, true, true, new NameTypePattern("uint64", "BigInteger"));
+    }
+
+    @Test
+    public void testNestedTypesInTypedef() {
 
-        GeneratedType parentContainer = null;
+        GeneratedTransferObject typeUnionTypedef = null;
+        int typeUnionTypedefCounter = 0;
 
         for (Type type : genTypes) {
-            if ((type instanceof GeneratedType) && !(type instanceof GeneratedTransferObject)) {
-                GeneratedType genTO = (GeneratedType) type;
-                if (genTO.getName().equals("ParentContainer")) {
-                    parentContainer = genTO;
-                    break;
+            if (type instanceof GeneratedType) {
+                GeneratedType genType = (GeneratedType) type;
+                if (genType.getName().equals("TypeUnion") && (genType instanceof GeneratedTransferObject)) {
+                    typeUnionTypedef = (GeneratedTransferObject) genType;
+                    typeUnionTypedefCounter++;
+                }
+            }
+        }
+
+        assertNotNull("TypeUnion TO wasn't found.", typeUnionTypedef);
+        assertEquals("TypeUnion TO has incorrect number of occurences.", 1, typeUnionTypedefCounter);
+
+        assertNotNull("TypeUnion TO wasn't found.", typeUnionTypedef);
+        assertEquals("TypeUnion TO has incorrect number of occurences.", 1, typeUnionTypedefCounter);
+        assertEquals("TypeUnion has incorrect package name.",
+                "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626", typeUnionTypedef.getPackageName());
+
+        assertEquals("TypeUnion generated TO has incorrect number of properties", 2, typeUnionTypedef.getProperties()
+                .size());
+        containsAttributes(typeUnionTypedef, true, true, true, new NameTypePattern("string", "String"));
+        containsAttributes(typeUnionTypedef, true, false, true, new NameTypePattern("typeUnion1", "TypeUnion1"));
+
+        List<GeneratedType> nestedUnions = typeUnionTypedef.getEnclosedTypes();
+        assertEquals("Incorrect number of nested unions", 2, nestedUnions.size());
+
+        GeneratedTransferObject typeUnion1 = null;
+        int typeUnion1Counter = 0;
+        GeneratedTransferObject typeUnion2 = null;
+        int typeUnion2Counter = 0;
+        for (GeneratedType genType : nestedUnions) {
+            if (genType instanceof GeneratedTransferObject) {
+                if (genType.getName().equals("TypeUnion1")) {
+                    typeUnion1 = (GeneratedTransferObject) genType;
+                    typeUnion1Counter++;
+                } else if (genType.getName().equals("TypeUnion2")) {
+                    typeUnion2 = (GeneratedTransferObject) genType;
+                    typeUnion2Counter++;
                 }
             }
         }
 
+        assertNotNull("TypeUnion1 TO wasn't found.", typeUnion1);
+        assertEquals("TypeUnion1 TO has incorrect number of occurences.", 1, typeUnion1Counter);
+
+        assertEquals("TypeUnion1 has incorrect package name.",
+                "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626", typeUnion1.getPackageName());
+
+        assertEquals("TypeUnion1 generated TO has incorrect number of properties", 4, typeUnion1.getProperties().size());
+        containsAttributes(typeUnion1, true, true, true, new NameTypePattern("uint32", "Long"));
+        containsAttributes(typeUnion1, true, true, true, new NameTypePattern("int8", "Byte"));
+        containsAttributes(typeUnion1, true, true, true, new NameTypePattern("string", "String"));
+        containsAttributes(typeUnion1, true, false, true, new NameTypePattern("typeUnion2", "TypeUnion2"));
+
+        assertNotNull("TypeUnion2 TO wasn't found.", typeUnion2);
+        assertEquals("TypeUnion2 TO has incorrect number of occurences.", 1, typeUnion2Counter);
+
+        assertEquals("TypeUnion2 has incorrect package name.",
+                "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626", typeUnion2.getPackageName());
+
+        assertEquals("TypeUnion2 generated TO has incorrect number of properties", 2, typeUnion2.getProperties().size());
+        containsAttributes(typeUnion2, true, true, true, new NameTypePattern("string", "String"));
+        containsAttributes(typeUnion2, true, true, true, new NameTypePattern("uint64", "BigInteger"));
+
+    }
+
+    @Test
+    public void bitAndUnionEnclosingTest() {
+
         assertNotNull("Parent container object wasn't found.", parentContainer);
+        containsMethods(parentContainer, new NameTypePattern("getLf", "Lf"));
 
         GeneratedTransferObject bitLeaf = null;
         GeneratedTransferObject unionLeaf = null;
@@ -74,8 +213,8 @@ public class BitAndUnionTOEnclosingTest {
             }
         }
 
-        assertNotNull("BitLeaf TO builder wasn't found.", bitLeaf);
-        assertNotNull("UnionLeaf TO builder wasn't found.", unionLeaf);
+        assertNotNull("BitLeaf TO wasn't found.", bitLeaf);
+        assertNotNull("UnionLeaf TO wasn't found.", unionLeaf);
 
         assertEquals("BitLeaf has incorrect package name.",
                 "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626.ParentContainer",
@@ -88,6 +227,7 @@ public class BitAndUnionTOEnclosingTest {
         GeneratedProperty firstBitProperty = null;
         GeneratedProperty secondBitProperty = null;
         GeneratedProperty thirdBitProperty = null;
+
         for (GeneratedProperty genProperty : propertiesBitLeaf) {
             if (genProperty.getName().equals("firstBit")) {
                 firstBitProperty = genProperty;
@@ -129,4 +269,5 @@ public class BitAndUnionTOEnclosingTest {
         assertEquals("uint8 property has incorrect type", "Short", uint8Property.getReturnType().getName());
 
     }
+
 }
index 6d22a01dc48b6341a2894290c35ace262bb0534f..3f3bd0f1a0658180723690bf9c4936ef3b54ad62 100644 (file)
@@ -86,41 +86,41 @@ public class ChoiceCaseGenTypesTest {
         checkGeneratedType(genTypes, "LockType", pcgPref); // choice
 
         genType = checkGeneratedType(genTypes, "GlobalLock", pcgPref + ".lock.type"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getGlobalLock", "GlobalLock"));
+        containsMethods(genType, new NameTypePattern("getGlobalLock", "GlobalLock"));
         containsInterface("LockType", genType);
 
         genType = checkGeneratedType(genTypes, "PartialLock", pcgPref + ".lock.type"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getPartialLock", "List<PartialLock>"));
+        containsMethods(genType, new NameTypePattern("getPartialLock", "List<PartialLock>"));
         containsInterface("LockType", genType);
 
         genType = checkGeneratedType(genTypes, "Fingerprint", pcgPref + ".lock.type"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getAlgorithmAndHash", "AlgorithmAndHash"));
+        containsMethods(genType, new NameTypePattern("getAlgorithmAndHash", "AlgorithmAndHash"));
         containsInterface("LockType", genType);
 
         genType = checkGeneratedType(genTypes, "AlgorithmAndHash", pcgPref + ".lock.type.fingerprint"); // choice
 
         genType = checkGeneratedType(genTypes, "Md5", pcgPref + ".lock.type.fingerprint.algorithm.and.hash"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getMd5", "TlsFingerprintType"));
+        containsMethods(genType, new NameTypePattern("getMd5", "TlsFingerprintType"));
         containsInterface("AlgorithmAndHash", genType);
 
         genType = checkGeneratedType(genTypes, "Sha1", pcgPref + ".lock.type.fingerprint.algorithm.and.hash"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getSha1", "TlsFingerprintType"));
+        containsMethods(genType, new NameTypePattern("getSha1", "TlsFingerprintType"));
         containsInterface("AlgorithmAndHash", genType);
 
         genType = checkGeneratedType(genTypes, "Sha224", pcgPref + ".lock.type.fingerprint.algorithm.and.hash"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getSha224", "TlsFingerprintType"));
+        containsMethods(genType, new NameTypePattern("getSha224", "TlsFingerprintType"));
         containsInterface("AlgorithmAndHash", genType);
 
         genType = checkGeneratedType(genTypes, "Sha256", pcgPref + ".lock.type.fingerprint.algorithm.and.hash"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getSha256", "TlsFingerprintType"));
+        containsMethods(genType, new NameTypePattern("getSha256", "TlsFingerprintType"));
         containsInterface("AlgorithmAndHash", genType);
 
         genType = checkGeneratedType(genTypes, "Sha384", pcgPref + ".lock.type.fingerprint.algorithm.and.hash"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getSha384", "TlsFingerprintType"));
+        containsMethods(genType, new NameTypePattern("getSha384", "TlsFingerprintType"));
         containsInterface("AlgorithmAndHash", genType);
 
         genType = checkGeneratedType(genTypes, "Sha512", pcgPref + ".lock.type.fingerprint.algorithm.and.hash"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getSha512", "TlsFingerprintType"));
+        containsMethods(genType, new NameTypePattern("getSha512", "TlsFingerprintType"));
         containsInterface("AlgorithmAndHash", genType);
 
         // test for file augment-monitoring
@@ -131,24 +131,24 @@ public class ChoiceCaseGenTypesTest {
 
         genType = checkGeneratedType(genTypes, "AutonomousLock", pcgPref
                 + ".netconf.state.datastores.datastore.locks.lock.type"); // choice
-        containsSignatures(genType, new MethodSignaturePattern("getAutonomousDef", "AutonomousDef"));
+        containsMethods(genType, new NameTypePattern("getAutonomousDef", "AutonomousDef"));
         containsInterface("LockType", genType);
 
         genType = checkGeneratedType(genTypes, "AnonymousLock", pcgPref
                 + ".netconf.state.datastores.datastore.locks.lock.type"); // choice
-        containsSignatures(genType, new MethodSignaturePattern("getLockTime", "Long"));
+        containsMethods(genType, new NameTypePattern("getLockTime", "Long"));
         containsInterface("LockType", genType);
 
         genType = checkGeneratedType(genTypes, "LeafAugCase", pcgPref
                 + ".netconf.state.datastores.datastore.locks.lock.type"); // choice
-        containsSignatures(genType, new MethodSignaturePattern("getLeafAugCase", "String"));
+        containsMethods(genType, new NameTypePattern("getLeafAugCase", "String"));
         containsInterface("LockType", genType);
 
         // augment
         // "/nm:netconf-state/nm:datastores/nm:datastore/nm:locks/nm:lock-type/nm:partial-lock"
         // {
         genType = checkGeneratedType(genTypes, "PartialLock1", pcgPref); // case
-        containsSignatures(genType, new MethodSignaturePattern("getAugCaseByChoice", "AugCaseByChoice"));
+        containsMethods(genType, new NameTypePattern("getAugCaseByChoice", "AugCaseByChoice"));
         containsInterface("Augmentation<PartialLock>", genType);
 
         genType = checkGeneratedType(genTypes, "AugCaseByChoice", pcgPref
@@ -156,32 +156,32 @@ public class ChoiceCaseGenTypesTest {
 
         genType = checkGeneratedType(genTypes, "Foo", pcgPref
                 + ".netconf.state.datastores.datastore.locks.lock.type.partial.lock.aug._case.by.choice"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getFoo", "String"));
+        containsMethods(genType, new NameTypePattern("getFoo", "String"));
         containsInterface("AugCaseByChoice", genType);
 
         genType = checkGeneratedType(genTypes, "Bar", pcgPref
                 + ".netconf.state.datastores.datastore.locks.lock.type.partial.lock.aug._case.by.choice"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getBar", "Boolean"));
+        containsMethods(genType, new NameTypePattern("getBar", "Boolean"));
         containsInterface("AugCaseByChoice", genType);
 
         // augment "/nm:netconf-state/nm:datastores/nm:datastore" {
         genType = checkGeneratedType(genTypes, "Datastore1", pcgPref);
-        containsSignatures(genType, new MethodSignaturePattern("getStorageFormat", "StorageFormat"));
+        containsMethods(genType, new NameTypePattern("getStorageFormat", "StorageFormat"));
         containsInterface("Augmentation<Datastore>", genType);
 
         genType = checkGeneratedType(genTypes, "StorageFormat", pcgPref + ".netconf.state.datastores.datastore"); // choice
 
         genType = checkGeneratedType(genTypes, "UnknownFiles", pcgPref
                 + ".netconf.state.datastores.datastore.storage.format"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getFiles", "List<Files>"));
+        containsMethods(genType, new NameTypePattern("getFiles", "List<Files>"));
         containsInterface("StorageFormat", genType);
 
         genType = checkGeneratedType(genTypes, "Xml", pcgPref + ".netconf.state.datastores.datastore.storage.format"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getXmlDef", "XmlDef"));
+        containsMethods(genType, new NameTypePattern("getXmlDef", "XmlDef"));
         containsInterface("StorageFormat", genType);
 
         genType = checkGeneratedType(genTypes, "Yang", pcgPref + ".netconf.state.datastores.datastore.storage.format"); // case
-        containsSignatures(genType, new MethodSignaturePattern("getYangFileName", "String"));
+        containsMethods(genType, new NameTypePattern("getYangFileName", "String"));
         containsInterface("StorageFormat", genType);
 
     }
@@ -1,12 +1,12 @@
 package org.opendaylight.yangtools.sal.binding.generator.impl;
 
-public class MethodSignaturePattern {
+public class NameTypePattern {
     final String name;
     final String type;
 
-    public MethodSignaturePattern(String methodName, String methodType) {
-        this.name = methodName;
-        this.type = methodType;
+    public NameTypePattern(String name, String type) {
+        this.name = name;
+        this.type = type;
     }
 
     public String getName() {
index 3a10c24a51583f38ed3264e6002790c7c1510008..acaf426cf981eebdca10e8a061c6da7318e0981d 100644 (file)
@@ -5,6 +5,8 @@ import static org.junit.Assert.assertTrue;
 
 import java.util.List;
 
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;
 import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature;
 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType;
@@ -12,14 +14,13 @@ import org.opendaylight.yangtools.sal.binding.model.api.Type;
 
 public class SupportTestUtil {
 
-    public static void containsSignatures(final GeneratedType genType,
-            final MethodSignaturePattern... searchedSignsWhat) {
+    public static void containsMethods(final GeneratedType genType, final NameTypePattern... searchedSignsWhat) {
         final List<MethodSignature> searchedSignsIn = genType.getMethodDefinitions();
-        containsSignatures(searchedSignsIn, searchedSignsWhat);
+        containsMethods(searchedSignsIn, searchedSignsWhat);
     }
 
-    public static void containsSignatures(final List<MethodSignature> searchedSignsIn,
-            final MethodSignaturePattern... searchedSignsWhat) {
+    public static void containsMethods(final List<MethodSignature> searchedSignsIn,
+            final NameTypePattern... searchedSignsWhat) {
         if (searchedSignsIn == null) {
             throw new IllegalArgumentException("List of method signatures in which should be searched can't be null");
         }
@@ -27,7 +28,7 @@ public class SupportTestUtil {
             throw new IllegalArgumentException("Array of method signatures which should be searched can't be null");
         }
 
-        for (MethodSignaturePattern searchedSignWhat : searchedSignsWhat) {
+        for (NameTypePattern searchedSignWhat : searchedSignsWhat) {
             boolean nameMatchFound = false;
             String typeNameFound = "";
             for (MethodSignature searchedSignIn : searchedSignsIn) {
@@ -46,6 +47,48 @@ public class SupportTestUtil {
         }
     }
 
+    public static void containsAttributes(final GeneratedTransferObject genTO, boolean equal, boolean hash,
+            boolean toString, final NameTypePattern... searchedSignsWhat) {
+        List<GeneratedProperty> searchedPropertiesIn = genTO.getProperties();
+        containsAttributes(searchedPropertiesIn, "", searchedSignsWhat);
+        if (equal) {
+            searchedPropertiesIn = genTO.getEqualsIdentifiers();
+            containsAttributes(searchedPropertiesIn, "equal", searchedSignsWhat);
+        }
+        if (hash) {
+            searchedPropertiesIn = genTO.getHashCodeIdentifiers();
+            containsAttributes(searchedPropertiesIn, "hash", searchedSignsWhat);
+        }
+        if (toString) {
+            searchedPropertiesIn = genTO.getToStringIdentifiers();
+            containsAttributes(searchedPropertiesIn, "toString", searchedSignsWhat);
+        }
+
+    }
+
+    public static void containsAttributes(final List<GeneratedProperty> searchedPropertiesIn, final String listType,
+            final NameTypePattern... searchedPropertiesWhat) {
+
+        for (NameTypePattern searchedPropertyWhat : searchedPropertiesWhat) {
+            boolean nameMatchFound = false;
+            String typeNameFound = "";
+            for (GeneratedProperty searchedPropertyIn : searchedPropertiesIn) {
+                if (searchedPropertyWhat.getName().equals(searchedPropertyIn.getName())) {
+                    nameMatchFound = true;
+                    typeNameFound = resolveFullNameOfReturnType(searchedPropertyIn.getReturnType());
+                    if (searchedPropertyWhat.getType().equals(typeNameFound)) {
+                        break;
+                    }
+                }
+            }
+            assertTrue("Property " + searchedPropertyWhat.getName() + " wasn't found in " + listType
+                    + " property list.", nameMatchFound);
+            assertEquals("The type of property " + searchedPropertyWhat.getName() + " in " + listType
+                    + " property list doesn't match expected type.", searchedPropertyWhat.getType(), typeNameFound);
+
+        }
+    }
+
     public static String resolveFullNameOfReturnType(final Type type) {
         final StringBuilder nameBuilder = new StringBuilder();
         if (type instanceof ParameterizedType) {
index 6a75b97db6da6090ef927fead5f120458f6825c4..0c57435d3ede3ca3f9fd885936737af8f0a8fdfe 100644 (file)
@@ -135,8 +135,8 @@ public class UsesTest {
 
         assertEquals("Number of method in GroupingCaseTest is incorrect", 1, groupingCaseTest.getMethodDefinitions()
                 .size());
-        containsSignatures(groupingCaseTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getLeafGroupingCaseTest1", "String"));
+        containsMethods(groupingCaseTest.getMethodDefinitions(), new NameTypePattern("getLeafGroupingCaseTest1",
+                "String"));
     }
 
     @Test
@@ -186,12 +186,11 @@ public class UsesTest {
                 .getMethodDefinitions().size());
         assertEquals("Number of method in ContainerTest is incorrect", 1, containerTest.getMethodDefinitions().size());
 
-        containsSignatures(groupingContainerTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getLeafGroupingContainerTest1", "String"), new MethodSignaturePattern("getLeafGroupingContainerTest2",
+        containsMethods(groupingContainerTest.getMethodDefinitions(), new NameTypePattern(
+                "getLeafGroupingContainerTest1", "String"), new NameTypePattern("getLeafGroupingContainerTest2",
                 "Short"));
 
-        containsSignatures(containerTest.getMethodDefinitions(), new MethodSignaturePattern("getContainerLeafTest",
-                "String"));
+        containsMethods(containerTest.getMethodDefinitions(), new NameTypePattern("getContainerLeafTest", "String"));
     }
 
     @Test
@@ -240,11 +239,10 @@ public class UsesTest {
                 .getMethodDefinitions().size());
         assertEquals("Number of method in GroupingTest is incorrect", 1, groupingTest.getMethodDefinitions().size());
 
-        containsSignatures(groupingGroupingTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getLeafGroupingGrouping", "String"));
+        containsMethods(groupingGroupingTest.getMethodDefinitions(), new NameTypePattern("getLeafGroupingGrouping",
+                "String"));
 
-        containsSignatures(groupingTest.getMethodDefinitions(), new MethodSignaturePattern("getLeafGroupingTest",
-                "Byte"));
+        containsMethods(groupingTest.getMethodDefinitions(), new NameTypePattern("getLeafGroupingTest", "Byte"));
     }
 
     @Test
@@ -319,15 +317,15 @@ public class UsesTest {
         assertEquals("Number of method in ListGroupingListTest is incorrect", 1, listGroupingListTest
                 .getMethodDefinitions().size());
 
-        containsSignatures(groupingListTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getContainerGroupingListTest", "ContainerGroupingListTest"), new MethodSignaturePattern(
-                "getLeafGroupingListTest", "String"), new MethodSignaturePattern("getLeaffllistGroupingListTest",
-                "List<String>"), new MethodSignaturePattern("getListGroupingListTest", "List<ListGroupingListTest>"));
-        containsSignatures(listTest.getMethodDefinitions(), new MethodSignaturePattern("getListLeafTest", "String"));
-        containsSignatures(containerGroupingListTest.getMethodDefinitions(), new MethodSignaturePattern(
+        containsMethods(groupingListTest.getMethodDefinitions(), new NameTypePattern("getContainerGroupingListTest",
+                "ContainerGroupingListTest"), new NameTypePattern("getLeafGroupingListTest", "String"),
+                new NameTypePattern("getLeaffllistGroupingListTest", "List<String>"), new NameTypePattern(
+                        "getListGroupingListTest", "List<ListGroupingListTest>"));
+        containsMethods(listTest.getMethodDefinitions(), new NameTypePattern("getListLeafTest", "String"));
+        containsMethods(containerGroupingListTest.getMethodDefinitions(), new NameTypePattern(
                 "getLeafContainerGroupingListTest", "Short"));
-        containsSignatures(listGroupingListTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getLeafListGroupingListTest", "Integer"));
+        containsMethods(listGroupingListTest.getMethodDefinitions(), new NameTypePattern("getLeafListGroupingListTest",
+                "Integer"));
     }
 
     @Test
@@ -378,8 +376,8 @@ public class UsesTest {
         assertEquals("Number of method in GroupingModulTest is incorrect", 2, groupingModulTest.getMethodDefinitions()
                 .size());
 
-        containsSignatures(groupingModulTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getLeafGroupingModulTest", "String"), new MethodSignaturePattern("getLeafGroupingModulTest2", "Short"));
+        containsMethods(groupingModulTest.getMethodDefinitions(), new NameTypePattern("getLeafGroupingModulTest",
+                "String"), new NameTypePattern("getLeafGroupingModulTest2", "Short"));
     }
 
     @Test
@@ -467,12 +465,12 @@ public class UsesTest {
         assertEquals("Number of method in ContainerGroupingRpcInputTest is incorrect", 1, containerGroupingRpcInputTest
                 .getMethodDefinitions().size());
 
-        containsSignatures(groupingRpcInputTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getContainerGroupingRpcInputTest", "ContainerGroupingRpcInputTest"), new MethodSignaturePattern(
+        containsMethods(groupingRpcInputTest.getMethodDefinitions(), new NameTypePattern(
+                "getContainerGroupingRpcInputTest", "ContainerGroupingRpcInputTest"), new NameTypePattern(
                 "getLeaflistGroupingRpcInputTest", "List<Short>"));
-        containsSignatures(groupingRpcOutputTest.getMethodDefinitions(), new MethodSignaturePattern(
+        containsMethods(groupingRpcOutputTest.getMethodDefinitions(), new NameTypePattern(
                 "getLeafGroupingRpcOutputTest", "Byte"));
-        containsSignatures(containerGroupingRpcInputTest.getMethodDefinitions(), new MethodSignaturePattern(
+        containsMethods(containerGroupingRpcInputTest.getMethodDefinitions(), new NameTypePattern(
                 "getLeafContainerGroupingRpcInputTest", "String"));
     }
 
@@ -526,8 +524,8 @@ public class UsesTest {
         assertEquals("Number of method in GroupingCaseTest is incorrect", 1, groupingAugmentTest.getMethodDefinitions()
                 .size());
 
-        containsSignatures(groupingAugmentTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getLeafGroupingAugmentTest", "String"));
+        containsMethods(groupingAugmentTest.getMethodDefinitions(), new NameTypePattern("getLeafGroupingAugmentTest",
+                "String"));
     }
 
     @Test
@@ -594,12 +592,12 @@ public class UsesTest {
         assertEquals("Number of method in ContainerGroupingNotificationTest is incorrect", 1,
                 containerGroupingNotificationTest.getMethodDefinitions().size());
 
-        containsSignatures(notificationTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getLeafNotificationTest", "String"));
-        containsSignatures(groupingNotificationTest.getMethodDefinitions(), new MethodSignaturePattern(
-                "getContainerGroupingNotificationTest", "ContainerGroupingNotificationTest"),
-                new MethodSignaturePattern("getLeaffllistGroupingNotificationTest", "List<String>"));
-        containsSignatures(containerGroupingNotificationTest.getMethodDefinitions(), new MethodSignaturePattern(
+        containsMethods(notificationTest.getMethodDefinitions(), new NameTypePattern("getLeafNotificationTest",
+                "String"));
+        containsMethods(groupingNotificationTest.getMethodDefinitions(), new NameTypePattern(
+                "getContainerGroupingNotificationTest", "ContainerGroupingNotificationTest"), new NameTypePattern(
+                "getLeaffllistGroupingNotificationTest", "List<String>"));
+        containsMethods(containerGroupingNotificationTest.getMethodDefinitions(), new NameTypePattern(
                 "getLeafContainerGroupingNotificationTest", "Long"));
     }
 
similarity index 69%
rename from code-generator/binding-generator-impl/src/test/resources/bit_and_union_in_leaf.yang
rename to code-generator/binding-generator-impl/src/test/resources/bit_and_union.yang
index b5279b0b6a846c511c3eea72d4d49562d73ba534..6f762226336c4029efdbf278d38f49024cf9f0ac 100644 (file)
@@ -51,5 +51,40 @@ module bit-and-union-in-leaf {
                 type uint8;
             }
         }
+        
+// nested union in leaf   
+        leaf lf {
+            type union {
+                               type string;
+                               type union {
+                                       type uint32;
+                                       type int8;
+                                       type string;
+                                       type union {
+                                               type string;
+                                               type uint64;
+                                       }       
+                               }
+                       }               
+               }        
     }
+    
+
+
+// nested union in typedef     
+       typedef type-union {
+               type union {
+                       type string;
+                       type union {
+                               type uint32;
+                               type int8;
+                               type string;    
+                               type union {
+                                       type string;
+                                       type uint64;
+                               }                               
+                       }
+               }       
+               
+       }    
 }
\ No newline at end of file