YANG uses and UT

Change-Id: Id3ec5cfed2b8e2a7d2d580786c70b5804f03ecfa
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 51f3928..c1c84a1 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
@@ -52,8 +52,8 @@
 import org.onosproject.yangutils.parser.impl.listeners.MaxElementsListener;
 import org.onosproject.yangutils.parser.impl.listeners.MinElementsListener;
 import org.onosproject.yangutils.parser.impl.listeners.ModuleListener;
-import org.onosproject.yangutils.parser.impl.listeners.NotificationListener;
 import org.onosproject.yangutils.parser.impl.listeners.NamespaceListener;
+import org.onosproject.yangutils.parser.impl.listeners.NotificationListener;
 import org.onosproject.yangutils.parser.impl.listeners.OrganizationListener;
 import org.onosproject.yangutils.parser.impl.listeners.OutputListener;
 import org.onosproject.yangutils.parser.impl.listeners.PatternRestrictionListener;
@@ -1087,14 +1087,6 @@
     }
 
     @Override
-    public void enterInputStatementBody(GeneratedYangParser.InputStatementBodyContext ctx) {
-    }
-
-    @Override
-    public void exitInputStatementBody(GeneratedYangParser.InputStatementBodyContext ctx) {
-    }
-
-    @Override
     public void enterOutputStatement(GeneratedYangParser.OutputStatementContext ctx) {
         OutputListener.processOutputEntry(this, ctx);
     }
@@ -1105,14 +1097,6 @@
     }
 
     @Override
-    public void enterOutputStatementBody(GeneratedYangParser.OutputStatementBodyContext ctx) {
-    }
-
-    @Override
-    public void exitOutputStatementBody(GeneratedYangParser.OutputStatementBodyContext ctx) {
-    }
-
-    @Override
     public void enterNotificationStatement(GeneratedYangParser.NotificationStatementContext ctx) {
         NotificationListener.processNotificationEntry(this, ctx);
     }
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
index c81e554..67dacbb 100644
--- 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
@@ -46,12 +46,10 @@
 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
@@ -168,7 +166,5 @@
         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/InputListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/InputListener.java
index bb1ba85..78a5153 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/InputListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/InputListener.java
@@ -36,6 +36,8 @@
 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.validateCardinalityNonZero;
+import static org.onosproject.yangutils.utils.YangConstructType.DATA_DEF_DATA;
 import static org.onosproject.yangutils.utils.YangConstructType.INPUT_DATA;
 
 /*
@@ -86,6 +88,9 @@
         // Check for stack to be non empty.
         checkStackIsNotEmpty(listener, MISSING_HOLDER, INPUT_DATA, "", ENTRY);
 
+        validateCardinalityNonZero(ctx.dataDefStatement(), DATA_DEF_DATA,
+                INPUT_DATA, "", ctx);
+
         Parsable curData = listener.getParsedDataStack().peek();
         if (curData instanceof YangRpc) {
 
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 a6c5496..42326b7 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
@@ -19,6 +19,7 @@
 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;
@@ -140,7 +141,7 @@
         if (curData instanceof YangModule || curData instanceof YangContainer
                 || curData instanceof YangList || curData instanceof YangCase
                 || curData instanceof YangNotification || curData instanceof YangInput
-                || curData instanceof YangOutput || curData instanceof YangAugment) {
+                || curData instanceof YangOutput || curData instanceof YangAugment || curData instanceof YangGrouping) {
             curNode = (YangNode) curData;
             try {
                 curNode.addChild(yangList);
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/NotificationListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/NotificationListener.java
index 58daefb..1bd7390 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/NotificationListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/NotificationListener.java
@@ -40,13 +40,10 @@
 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.NOTIFICATION_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
@@ -159,7 +156,5 @@
                 ctx.identifier().getText());
         validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, NOTIFICATION_DATA,
                 ctx.identifier().getText());
-        validateMutuallyExclusiveChilds(ctx.typedefStatement(), TYPEDEF_DATA, ctx.groupingStatement(), GROUPING_DATA,
-                NOTIFICATION_DATA, ctx.identifier().getText());
     }
 }
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/OutputListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/OutputListener.java
index 2dfa2ed..83fec50 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/OutputListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/OutputListener.java
@@ -36,6 +36,8 @@
 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.validateCardinalityNonZero;
+import static org.onosproject.yangutils.utils.YangConstructType.DATA_DEF_DATA;
 import static org.onosproject.yangutils.utils.YangConstructType.OUTPUT_DATA;
 
 /*
@@ -86,6 +88,9 @@
         // Check for stack to be non empty.
         checkStackIsNotEmpty(listener, MISSING_HOLDER, OUTPUT_DATA, "", ENTRY);
 
+        validateCardinalityNonZero(ctx.dataDefStatement(), DATA_DEF_DATA,
+                OUTPUT_DATA, "", ctx);
+
         Parsable curData = listener.getParsedDataStack().peek();
         if (curData instanceof YangRpc) {
 
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/RpcListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/RpcListener.java
index ae9e04c..b440289 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/RpcListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/RpcListener.java
@@ -37,12 +37,9 @@
 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.RPC_DATA;
 import static org.onosproject.yangutils.utils.YangConstructType.INPUT_DATA;
 import static org.onosproject.yangutils.utils.YangConstructType.OUTPUT_DATA;
-import static org.onosproject.yangutils.utils.YangConstructType.TYPEDEF_DATA;
-import static org.onosproject.yangutils.utils.YangConstructType.GROUPING_DATA;
 import static org.onosproject.yangutils.utils.YangConstructType.STATUS_DATA;
 import static org.onosproject.yangutils.utils.YangConstructType.REFERENCE_DATA;
 import static org.onosproject.yangutils.utils.YangConstructType.DESCRIPTION_DATA;
@@ -157,8 +154,6 @@
         validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, RPC_DATA, ctx.identifier().getText());
         validateCardinalityMaxOne(ctx.inputStatement(), INPUT_DATA, RPC_DATA, ctx.identifier().getText());
         validateCardinalityMaxOne(ctx.outputStatement(), OUTPUT_DATA, RPC_DATA, ctx.identifier().getText());
-        validateMutuallyExclusiveChilds(ctx.typedefStatement(), TYPEDEF_DATA, ctx.groupingStatement(), GROUPING_DATA,
-                RPC_DATA, ctx.identifier().getText());
     }
 
 }
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeDefListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeDefListener.java
index bfa22a4..b0a3b69 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeDefListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeDefListener.java
@@ -17,6 +17,7 @@
 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;
@@ -127,11 +128,8 @@
 
         if (curData instanceof YangModule || curData instanceof YangSubModule || curData instanceof YangContainer
                 || curData instanceof YangList || curData instanceof YangNotification || curData instanceof YangRpc
-                || curData instanceof YangInput || curData instanceof YangOutput) {
+                || curData instanceof YangInput || curData instanceof YangOutput || curData instanceof YangGrouping) {
 
-            /*
-             * TODO YangGrouping.
-             */
             YangNode curNode = (YangNode) curData;
             try {
                 curNode.addChild(typeDefNode);
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
index 4e2925a..1658eee 100644
--- 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
@@ -23,8 +23,10 @@
 import org.onosproject.yangutils.datamodel.YangList;
 import org.onosproject.yangutils.datamodel.YangModule;
 import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
 import org.onosproject.yangutils.datamodel.YangNotification;
 import org.onosproject.yangutils.datamodel.YangOutput;
+import org.onosproject.yangutils.datamodel.YangResolutionInfo;
 import org.onosproject.yangutils.datamodel.YangSubModule;
 import org.onosproject.yangutils.datamodel.YangUses;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
@@ -33,16 +35,18 @@
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 import org.onosproject.yangutils.parser.impl.TreeWalkListener;
 
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
 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.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.getValidNodeIdentifier;
 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;
@@ -116,6 +120,11 @@
         // Validate sub statement cardinality.
         validateSubStatementsCardinality(ctx);
 
+        // Check for identifier collision
+        int line = ctx.getStart().getLine();
+        int charPositionInLine = ctx.getStart().getCharPositionInLine();
+
+        detectCollidingChildUtil(listener, line, charPositionInLine, ctx.string().getText(), USES_DATA);
         Parsable curData = listener.getParsedDataStack().peek();
 
         if (curData instanceof YangModule || curData instanceof YangSubModule
@@ -126,8 +135,8 @@
                 || curData instanceof YangNotification) {
 
             YangUses usesNode = getYangUsesNode(JAVA_GENERATION);
-            usesNode.setName(ctx.string().getText());
-
+            YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.string().getText(), USES_DATA, ctx);
+            usesNode.setNodeIdentifier(nodeIdentifier);
             YangNode curNode = (YangNode) curData;
 
             try {
@@ -156,12 +165,29 @@
         // 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,
+        Parsable parsableUses = listener.getParsedDataStack().pop();
+        if (!(parsableUses instanceof YangUses)) {
+            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, USES_DATA,
                     ctx.string().getText(), EXIT));
         }
+        YangUses uses = (YangUses) parsableUses;
+        int errorLine = ctx.getStart().getLine();
+        int errorPosition = ctx.getStart().getCharPositionInLine();
+
+        // Parent YANG node of uses to be added in resolution information.
+        Parsable parentNode = listener.getParsedDataStack().peek();
+
+        // Verify parent node of leaf
+        if (!(parentNode instanceof YangNode)) {
+            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, USES_DATA,
+                    ctx.string().getText(), EXIT));
+        }
+
+        // Add resolution information to the list
+        YangResolutionInfo resolutionInfo = new YangResolutionInfo<YangUses>(uses,
+                (YangNode) parentNode, errorLine,
+                errorPosition);
+        addToResolutionList(resolutionInfo, ctx);
     }
 
     // TODO linker to handle collision scenarios like leaf obtained by uses, conflicts with some existing leaf.
@@ -175,5 +201,23 @@
         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());    }
+        validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, USES_DATA, ctx.string().getText());
+    }
+
+    /**
+     * Add to resolution list.
+     *
+     * @param resolutionInfo resolution information.
+     * @param ctx context object of the grammar rule
+     */
+    private static void addToResolutionList(YangResolutionInfo<YangUses> resolutionInfo,
+            GeneratedYangParser.UsesStatementContext ctx) {
+
+        try {
+            addResolutionInfo(resolutionInfo);
+        } catch (DataModelException e) {
+            throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
+                    USES_DATA, ctx.string().getText(), EXIT, e.getMessage()));
+        }
+    }
 }