[ONOS-3894, 4071] YANG Advanced Construct Union & Grouping

Change-Id: I0f828adb5884c2d7b6e4120f9843c416608ae5e7
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
index 2436908..820139e 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
@@ -38,6 +38,7 @@
 import org.onosproject.yangutils.parser.impl.listeners.DescriptionListener;
 import org.onosproject.yangutils.parser.impl.listeners.EnumListener;
 import org.onosproject.yangutils.parser.impl.listeners.EnumerationListener;
+import org.onosproject.yangutils.parser.impl.listeners.GroupingListener;
 import org.onosproject.yangutils.parser.impl.listeners.ImportListener;
 import org.onosproject.yangutils.parser.impl.listeners.IncludeListener;
 import org.onosproject.yangutils.parser.impl.listeners.KeyListener;
@@ -61,7 +62,9 @@
 import org.onosproject.yangutils.parser.impl.listeners.SubModuleListener;
 import org.onosproject.yangutils.parser.impl.listeners.TypeDefListener;
 import org.onosproject.yangutils.parser.impl.listeners.TypeListener;
+import org.onosproject.yangutils.parser.impl.listeners.UnionListener;
 import org.onosproject.yangutils.parser.impl.listeners.UnitsListener;
+import org.onosproject.yangutils.parser.impl.listeners.UsesListener;
 import org.onosproject.yangutils.parser.impl.listeners.ValueListener;
 import org.onosproject.yangutils.parser.impl.listeners.VersionListener;
 
@@ -687,12 +690,12 @@
 
     @Override
     public void enterUnionSpecification(GeneratedYangParser.UnionSpecificationContext ctx) {
-        // TODO: implement the method.
+        UnionListener.processUnionEntry(this, ctx);
     }
 
     @Override
     public void exitUnionSpecification(GeneratedYangParser.UnionSpecificationContext ctx) {
-        // TODO: implement the method.
+        UnionListener.processUnionExit(this, ctx);
     }
 
     @Override
@@ -847,12 +850,12 @@
 
     @Override
     public void enterGroupingStatement(GeneratedYangParser.GroupingStatementContext ctx) {
-        // TODO: implement the method.
+        GroupingListener.processGroupingEntry(this, ctx);
     }
 
     @Override
     public void exitGroupingStatement(GeneratedYangParser.GroupingStatementContext ctx) {
-        // TODO: implement the method.
+        GroupingListener.processGroupingExit(this, ctx);
     }
 
     @Override
@@ -947,12 +950,12 @@
 
     @Override
     public void enterUsesStatement(GeneratedYangParser.UsesStatementContext ctx) {
-        // TODO: implement the method.
+        UsesListener.processUsesEntry(this, ctx);
     }
 
     @Override
     public void exitUsesStatement(GeneratedYangParser.UsesStatementContext ctx) {
-        // TODO: implement the method.
+        UsesListener.processUsesExit(this, ctx);
     }
 
     @Override
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ContainerListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ContainerListener.java
index 07dc946..06dd0d5 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ContainerListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ContainerListener.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.yangutils.parser.impl.listeners;
 
+import org.onosproject.yangutils.datamodel.YangCase;
 import org.onosproject.yangutils.datamodel.YangContainer;
 import org.onosproject.yangutils.datamodel.YangList;
 import org.onosproject.yangutils.datamodel.YangModule;
@@ -126,7 +127,7 @@
 
         Parsable curData = listener.getParsedDataStack().peek();
         if (curData instanceof YangModule || curData instanceof YangContainer
-                || curData instanceof YangList) {
+                || curData instanceof YangList || curData instanceof YangCase) {
             YangNode curNode = (YangNode) curData;
             try {
                 curNode.addChild(container);
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/EnumerationListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/EnumerationListener.java
index 0dab0f1..87d51b4 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/EnumerationListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/EnumerationListener.java
@@ -45,6 +45,7 @@
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangLeafList;
 import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.YangUnion;
 import org.onosproject.yangutils.parser.Parsable;
 import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
@@ -102,7 +103,10 @@
                 case LEAF_LIST_DATA:
                     enumerationNode.setEnumerationName(((YangLeafList) tmpData).getLeafName());
                     break;
-                // TODO typedef, union, deviate.
+                case UNION_DATA:
+                    enumerationNode.setEnumerationName(((YangUnion) tmpData).getUnionName());
+                    break;
+                // TODO typedef, deviate.
                 default:
                     throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
                             ((YangType<?>) typeData).getDataTypeName(), ENTRY));
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java
new file mode 100644
index 0000000..e35ce1f
--- /dev/null
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.parser.impl.listeners;
+
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangGrouping;
+import org.onosproject.yangutils.datamodel.YangInput;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNotification;
+import org.onosproject.yangutils.datamodel.YangOutput;
+import org.onosproject.yangutils.datamodel.YangRpc;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+
+import static org.onosproject.yangutils.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
+import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.getYangGroupingNode;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerCollisionDetector.detectCollidingChildUtil;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateMutuallyExclusiveChilds;
+import static org.onosproject.yangutils.utils.YangConstructType.DESCRIPTION_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.GROUPING_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.REFERENCE_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.STATUS_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.TYPEDEF_DATA;
+
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ *
+ * ABNF grammar as per RFC6020
+ * grouping-stmt       = grouping-keyword sep identifier-arg-str optsep
+ *                      (";" /
+ *                       "{" stmtsep
+ *                          ;; these stmts can appear in any order
+ *                          [status-stmt stmtsep]
+ *                           [description-stmt stmtsep]
+ *                           [reference-stmt stmtsep]
+ *                           *((typedef-stmt /
+ *                              grouping-stmt) stmtsep)
+ *                           *(data-def-stmt stmtsep)
+ *                       "}")
+ *
+ * ANTLR grammar rule
+ * groupingStatement : GROUPING_KEYWORD identifier (STMTEND | LEFT_CURLY_BRACE
+ *       (statusStatement | descriptionStatement | referenceStatement | typedefStatement | groupingStatement
+ *       | dataDefStatement)* RIGHT_CURLY_BRACE);
+ */
+
+/**
+ * Implements listener based call back function corresponding to the "grouping"
+ * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
+ */
+public final class GroupingListener {
+
+    /**
+     * Creates a new grouping listener.
+     */
+    private GroupingListener() {
+    }
+
+    /**
+     * It is called when parser enters grammar rule (grouping), it perform
+     * validations and updates the data model tree.
+     *
+     * @param listener listener's object
+     * @param ctx context object of the grammar rule
+     */
+    public static void processGroupingEntry(TreeWalkListener listener,
+                                        GeneratedYangParser.GroupingStatementContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, GROUPING_DATA, ctx.identifier().getText(), ENTRY);
+
+        // Check validity of identifier and remove double quotes.
+        String identifier = getValidIdentifier(ctx.identifier().getText(), GROUPING_DATA, ctx);
+
+        // Validate sub statement cardinality.
+        validateSubStatementsCardinality(ctx);
+
+        Parsable curData = listener.getParsedDataStack().peek();
+
+        // Check for identifier collision
+        int line = ctx.getStart().getLine();
+        int charPositionInLine = ctx.getStart().getCharPositionInLine();
+        detectCollidingChildUtil(listener, line, charPositionInLine, identifier, GROUPING_DATA);
+
+        if (curData instanceof YangModule || curData instanceof YangSubModule
+                || curData instanceof YangContainer || curData instanceof YangNotification
+                || curData instanceof YangList || curData instanceof YangGrouping
+                || curData instanceof YangRpc || curData instanceof YangInput
+                || curData instanceof YangOutput) {
+
+            YangGrouping groupingNode = getYangGroupingNode(JAVA_GENERATION);
+            groupingNode.setName(identifier);
+
+            YangNode curNode = (YangNode) curData;
+            try {
+                curNode.addChild(groupingNode);
+            } catch (DataModelException e) {
+                throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
+                        GROUPING_DATA, ctx.identifier().getText(), ENTRY, e.getMessage()));
+            }
+            listener.getParsedDataStack().push(groupingNode);
+        } else {
+            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
+                    GROUPING_DATA, ctx.identifier().getText(), ENTRY));
+        }
+    }
+
+    /**
+     * It is called when parser exits from grammar rule (grouping), it perform
+     * validations and update the data model tree.
+     *
+     * @param listener Listener's object
+     * @param ctx      context object of the grammar rule
+     */
+    public static void processGroupingExit(TreeWalkListener listener,
+                                         GeneratedYangParser.GroupingStatementContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, GROUPING_DATA, ctx.identifier().getText(), EXIT);
+
+        if (listener.getParsedDataStack().peek() instanceof YangGrouping) {
+            listener.getParsedDataStack().pop();
+        } else {
+            throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, GROUPING_DATA,
+                    ctx.identifier().getText(), EXIT));
+        }
+    }
+
+    /**
+     * Validates the cardinality of case sub-statements as per grammar.
+     *
+     * @param ctx context object of the grammar rule
+     */
+    private static void validateSubStatementsCardinality(GeneratedYangParser.GroupingStatementContext ctx) {
+
+        validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, GROUPING_DATA, ctx.identifier().getText());
+        validateCardinalityMaxOne(ctx.descriptionStatement(), DESCRIPTION_DATA, GROUPING_DATA,
+                ctx.identifier().getText());
+        validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, GROUPING_DATA, ctx.identifier().getText());
+        validateMutuallyExclusiveChilds(ctx.typedefStatement(), TYPEDEF_DATA, ctx.groupingStatement(), GROUPING_DATA,
+                GROUPING_DATA, ctx.identifier().getText());
+    }
+}
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
index 4c19e7a..fe5e451 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.yangutils.parser.impl.listeners;
 
+import org.onosproject.yangutils.datamodel.YangCase;
 import org.onosproject.yangutils.datamodel.YangContainer;
 import org.onosproject.yangutils.datamodel.YangList;
 import org.onosproject.yangutils.datamodel.YangModule;
@@ -133,7 +134,7 @@
 
         Parsable curData = listener.getParsedDataStack().peek();
         if (curData instanceof YangModule || curData instanceof YangContainer
-                || curData instanceof YangList) {
+                || curData instanceof YangList || curData instanceof YangCase) {
             curNode = (YangNode) curData;
             try {
                 curNode.addChild(yangList);
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
index 5d6a744..b000242 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
@@ -22,6 +22,8 @@
 import org.onosproject.yangutils.datamodel.YangLeafList;
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.datamodel.YangUnion;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.Parsable;
 import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
@@ -116,6 +118,17 @@
                 YangLeafList leafList = (YangLeafList) tmpData;
                 leafList.setDataType((YangType<?>) type);
                 break;
+            case UNION_DATA:
+                YangUnion unionNode = (YangUnion) tmpData;
+                try {
+                    unionNode.addToTypeList((YangType<?>) type);
+                } catch (DataModelException e) {
+                    ParserException parserException = new ParserException(e.getMessage());
+                    parserException.setLine(ctx.getStart().getLine());
+                    parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+                    throw parserException;
+                }
+                break;
             case TYPEDEF_DATA:
 
                 /* Prepare the base type info and set in derived type */
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UnionListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UnionListener.java
new file mode 100644
index 0000000..a983f79
--- /dev/null
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UnionListener.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.parser.impl.listeners;
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ *
+ * ABNF grammar as per RFC6020
+ * type-body-stmts     = numerical-restrictions /
+ *                       decimal64-specification /
+ *                      string-restrictions /
+ *                       enum-specification /
+ *                       leafref-specification /
+ *                       identityref-specification /
+ *                       instance-identifier-specification /
+ *                       bits-specification /
+ *                       union-specification
+ *
+ * union-specification = 1*(type-stmt stmtsep)
+ *
+ * ANTLR grammar rule
+ * typeBodyStatements : numericalRestrictions | stringRestrictions | enumSpecification
+ *                 | leafrefSpecification | identityrefSpecification | instanceIdentifierSpecification
+ *                 | bitsSpecification | unionSpecification;
+ *
+ * unionSpecification : typeStatement+;
+ */
+
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.YangUnion;
+import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.UNION_DATA;
+
+/**
+ * Implements listener based call back function corresponding to the "union" rule
+ * defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
+ */
+public final class UnionListener {
+    /**
+     * Creates a new union listener.
+     */
+    private UnionListener() {
+    }
+
+    /**
+     * It is called when parser enters grammar rule (union), it perform
+     * validations and updates the data model tree.
+     *
+     * @param listener listener's object
+     * @param ctx      context object of the grammar rule
+     */
+    public static void processUnionEntry(TreeWalkListener listener,
+                                         GeneratedYangParser.UnionSpecificationContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, UNION_DATA, "", ENTRY);
+
+        if (listener.getParsedDataStack().peek() instanceof YangType) {
+            YangUnion unionNode = new YangUnion();
+            Parsable typeData = listener.getParsedDataStack().pop();
+
+            // Check for stack to be non empty.
+            checkStackIsNotEmpty(listener, MISSING_HOLDER, UNION_DATA, "", ENTRY);
+
+            Parsable tmpData = listener.getParsedDataStack().peek();
+
+            switch (tmpData.getYangConstructType()) {
+                case LEAF_DATA:
+                    unionNode.setUnionName(((YangLeaf) tmpData).getLeafName());
+                    break;
+                case LEAF_LIST_DATA:
+                    unionNode.setUnionName(((YangLeafList) tmpData).getLeafName());
+                    break;
+                case UNION_DATA:
+                    unionNode.setUnionName(((YangUnion) tmpData).getUnionName());
+                    break;
+                // TODO typedef, deviate.
+                default:
+                    throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
+                            ((YangType<?>) typeData).getDataTypeName(), ENTRY));
+            }
+            listener.getParsedDataStack().push(typeData);
+            listener.getParsedDataStack().push(unionNode);
+        } else {
+            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, UNION_DATA, "", ENTRY));
+        }
+    }
+
+    /**
+     * It is called when parser exits from grammar rule (union), it perform
+     * validations and update the data model tree.
+     *
+     * @param listener Listener's object
+     * @param ctx      context object of the grammar rule
+     */
+    public static void processUnionExit(TreeWalkListener listener,
+                                       GeneratedYangParser.UnionSpecificationContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, UNION_DATA, "", EXIT);
+
+        Parsable tmpUnionNode = listener.getParsedDataStack().peek();
+        if (tmpUnionNode instanceof YangUnion) {
+            YangUnion unionNode = (YangUnion) tmpUnionNode;
+            listener.getParsedDataStack().pop();
+
+            // Check for stack to be non empty.
+            checkStackIsNotEmpty(listener, MISSING_HOLDER, UNION_DATA, "", EXIT);
+
+            Parsable tmpNode = listener.getParsedDataStack().peek();
+            switch (tmpNode.getYangConstructType()) {
+                case TYPE_DATA: {
+                    YangType<YangUnion> typeNode = (YangType<YangUnion>) tmpNode;
+                    typeNode.setDataTypeExtendedInfo(unionNode);
+                    break;
+                }
+                default:
+                    throw new ParserException(
+                            constructListenerErrorMessage(INVALID_HOLDER, UNION_DATA, "", EXIT));
+            }
+        } else {
+            throw new ParserException(
+                    constructListenerErrorMessage(MISSING_CURRENT_HOLDER, UNION_DATA, "", EXIT));
+        }
+    }
+}
\ No newline at end of file
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java
new file mode 100644
index 0000000..59e744e
--- /dev/null
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java
@@ -0,0 +1,164 @@
+package org.onosproject.yangutils.parser.impl.listeners;
+
+import org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangCase;
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangGrouping;
+import org.onosproject.yangutils.datamodel.YangInput;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNotification;
+import org.onosproject.yangutils.datamodel.YangOutput;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.YangUses;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+
+import static org.onosproject.yangutils.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
+import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.getYangUsesNode;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
+import static org.onosproject.yangutils.utils.YangConstructType.DESCRIPTION_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.REFERENCE_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.STATUS_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.USES_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.WHEN_DATA;
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ *
+ * ABNF grammar as per RFC6020
+ * data-def-stmt       = container-stmt /
+ *                      leaf-stmt /
+ *                      leaf-list-stmt /
+ *                      list-stmt /
+ *                      choice-stmt /
+ *                      anyxml-stmt /
+ *                      uses-stmt
+ *
+ * uses-stmt           = uses-keyword sep identifier-ref-arg-str optsep
+ *                       (";" /
+ *                        "{" stmtsep
+ *                            ;; these stmts can appear in any order
+ *                            [when-stmt stmtsep]
+ *                            *(if-feature-stmt stmtsep)
+ *                            [status-stmt stmtsep]
+ *                            [description-stmt stmtsep]
+ *                            [reference-stmt stmtsep]
+ *                            *(refine-stmt stmtsep)
+ *                            *(uses-augment-stmt stmtsep)
+ *                        "}")
+ *
+ * ANTLR grammar rule
+ * dataDefStatement : containerStatement
+ *                 | leafStatement
+ *                 | leafListStatement
+ *                 | listStatement
+ *                 | choiceStatement
+ *                 | usesStatement;
+ *
+ * usesStatement : USES_KEYWORD string (STMTEND | LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement
+ *                 | statusStatement | descriptionStatement | referenceStatement | refineStatement
+ *                 | usesAugmentStatement)* RIGHT_CURLY_BRACE);
+ */
+
+/**
+ * Implements listener based call back function corresponding to the "uses"
+ * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
+ */
+public final class UsesListener {
+
+    /**
+     * Creates a new uses listener.
+     */
+    private UsesListener() {
+    }
+
+    /**
+     * It is called when parser enters grammar rule (uses), it perform
+     * validations and updates the data model tree.
+     *
+     * @param listener listener's object
+     * @param ctx context object of the grammar rule
+     */
+    public static void processUsesEntry(TreeWalkListener listener, GeneratedYangParser.UsesStatementContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, USES_DATA, ctx.string().getText(), ENTRY);
+
+        // Validate sub statement cardinality.
+        validateSubStatementsCardinality(ctx);
+
+        Parsable curData = listener.getParsedDataStack().peek();
+
+        if (curData instanceof YangModule || curData instanceof YangSubModule
+                || curData instanceof YangContainer || curData instanceof YangList
+                || curData instanceof YangUses || curData instanceof YangAugment
+                || curData instanceof YangCase || curData instanceof YangGrouping
+                || curData instanceof YangInput || curData instanceof YangOutput
+                || curData instanceof YangNotification) {
+
+            YangUses usesNode = getYangUsesNode(JAVA_GENERATION);
+            usesNode.setName(ctx.string().getText());
+
+            YangNode curNode = (YangNode) curData;
+
+            try {
+                curNode.addChild(usesNode);
+            } catch (DataModelException e) {
+                throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
+                        USES_DATA, ctx.string().getText(), ENTRY, e.getMessage()));
+            }
+            listener.getParsedDataStack().push(usesNode);
+        } else {
+            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
+                    USES_DATA, ctx.string().getText(), ENTRY));
+        }
+    }
+
+    /**
+     * It is called when parser exits from grammar rule (uses), it perform
+     * validations and update the data model tree.
+     *
+     * @param listener Listener's object
+     * @param ctx      context object of the grammar rule
+     */
+    public static void processUsesExit(TreeWalkListener listener,
+                                           GeneratedYangParser.UsesStatementContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, USES_DATA, ctx.string().getText(), EXIT);
+
+        if (listener.getParsedDataStack().peek() instanceof YangUses) {
+            listener.getParsedDataStack().pop();
+        } else {
+            throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, USES_DATA,
+                    ctx.string().getText(), EXIT));
+        }
+    }
+
+    // TODO linker to handle collision scenarios like leaf obtained by uses, conflicts with some existing leaf.
+
+    /**
+     * Validates the cardinality of case sub-statements as per grammar.
+     *
+     * @param ctx context object of the grammar rule
+     */
+    private static void validateSubStatementsCardinality(GeneratedYangParser.UsesStatementContext ctx) {
+        validateCardinalityMaxOne(ctx.whenStatement(), WHEN_DATA, USES_DATA, ctx.string().getText());
+        validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, USES_DATA, ctx.string().getText());
+        validateCardinalityMaxOne(ctx.descriptionStatement(), DESCRIPTION_DATA, USES_DATA, ctx.string().getText());
+        validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, USES_DATA, ctx.string().getText());    }
+}
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
index 39a9bae..8c3f36f 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
@@ -23,6 +23,7 @@
 import java.util.Calendar;
 import java.util.regex.Pattern;
 
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
 import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
 import org.onosproject.yangutils.utils.YangConstructType;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
@@ -43,6 +44,7 @@
     private static final String HYPHEN = "-";
     private static final String SLASH = "/";
     private static final String SPACE = " ";
+    private static final String COLON = ":";
 
     /**
      * Creates a new listener util.
@@ -204,4 +206,35 @@
                 EMPTY_STRING);
         return dateForRevision;
     }
+
+    /**
+     * Checks and return valid node identifier.
+     *
+     * @param nodeIdentifierString string from yang file
+     * @param yangConstruct yang construct for creating error message
+     * @param ctx yang construct's context to get the line number and character position
+     * @return valid node identifier
+     */
+    public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString, YangConstructType
+            yangConstruct, ParserRuleContext ctx) {
+        String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
+        String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
+        if (tmpData.length == 1) {
+            YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
+            nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct, ctx));
+            return nodeIdentifier;
+        } else if (tmpData.length == 2) {
+            YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
+            nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct, ctx));
+            nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct, ctx));
+            return nodeIdentifier;
+        } else {
+            ParserException parserException = new ParserException("YANG file error : " +
+                    YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
+                    " is not valid.");
+            parserException.setLine(ctx.getStart().getLine());
+            parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+            throw parserException;
+        }
+    }
 }
\ No newline at end of file