[ONOS-4842] Leafref implementation for augment and uses
Change-Id: I919553a64d683aff65a8f16e2de783702dd5a45f
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java
index 5171e2f..04d7f50 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/GroupingListener.java
@@ -106,6 +106,8 @@
         // Validate sub statement cardinality.
         validateSubStatementsCardinality(ctx);
 
+        // Increase the grouping count by one.
+        listener.increaseGroupingDepth();
         Parsable curData = listener.getParsedDataStack().peek();
 
         // Check for identifier collision
@@ -149,6 +151,8 @@
         // Check for stack to be non empty.
         checkStackIsNotEmpty(listener, MISSING_HOLDER, GROUPING_DATA, ctx.identifier().getText(), EXIT);
 
+        // Decrease the grouping count by one.
+        listener.decreaseGroupingDepth();
         if (listener.getParsedDataStack().peek() instanceof YangGrouping) {
             listener.getParsedDataStack().pop();
         } else {
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
index 6ada8c5..ef4237b 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
@@ -100,6 +100,8 @@
 
         YangLeafRef<?> leafRef = new YangLeafRef<>();
 
+        leafRef.setLineNumber(errorLine);
+        leafRef.setCharPosition(errorPosition);
         Parsable typeData = listener.getParsedDataStack().pop();
 
         if (!(typeData instanceof YangType)) {
@@ -130,11 +132,13 @@
                 }
 
                 leafRef.setResolvableStatus(UNRESOLVED);
-
-                // Add resolution information to the list.
-                YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
-                        (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
-                addToResolutionList(resolutionInfo);
+                leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeaf);
+                if (listener.getGroupingDepth() == 0) {
+                    // Add resolution information to the list.
+                    YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
+                            (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
+                    addToResolutionList(resolutionInfo);
+                }
                 break;
 
             case LEAF_LIST_DATA:
@@ -151,14 +155,19 @@
                 }
 
                 leafRef.setResolvableStatus(UNRESOLVED);
+                leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafList);
 
-                // Add resolution information to the list.
-                YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
-                        (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
-                addToResolutionList(resolutionInfoImpl);
+                if (listener.getGroupingDepth() == 0) {
+                    // Add resolution information to the list.
+                    YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
+                            (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
+                    addToResolutionList(resolutionInfoImpl);
+                }
                 break;
 
             case TYPEDEF_DATA:
+                Parsable parentNodeOfLeafref = listener.getParsedDataStack().peek();
+                leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafref);
                 /*
                  * Do not add the leaf ref to resolution list. It needs to be
                  * added to resolution list, when leaf/leaf list references to
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
index d0e7300..1891595 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ListListener.java
@@ -54,6 +54,7 @@
 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.ListenerUtil.validateUniqueInList;
 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.validateCardinalityNonZero;
@@ -174,6 +175,7 @@
             YangList yangList = (YangList) listener.getParsedDataStack().peek();
             try {
                 yangList.validateDataOnExit();
+                validateUniqueInList(yangList, ctx);
             } catch (DataModelException e) {
                 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
                         LIST_DATA, ctx.identifier().getText(), EXIT, e.getMessage()));
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UniqueListener.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UniqueListener.java
new file mode 100644
index 0000000..59920fe
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UniqueListener.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016-present 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.YangList;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.datamodel.utils.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.YangConstructType.UNIQUE_DATA;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+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_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ *
+ * ABNF grammar as per RFC6020
+ * unique-stmt         = unique-keyword sep unique-arg-str stmtend
+ *
+ * ANTLR grammar rule
+ * uniqueStatement: UNIQUE_KEYWORD unique STMTEND;
+ * unique : string;
+ */
+
+/**
+ * Represesnts listener based call back function corresponding to the "unique" rule
+ * defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
+ */
+public final class UniqueListener {
+
+    /**
+     * Creates a new unique listener.
+     */
+    private UniqueListener() {
+    }
+
+    /**
+     * It is called when parser receives an input matching the grammar rule
+     * (unique), perform validations and updates the data model tree.
+     *
+     * @param listener listener's object
+     * @param ctx      context object of the grammar rule
+     */
+    public static void processUniqueEntry(TreeWalkListener listener,
+                                          GeneratedYangParser.UniqueStatementContext ctx) {
+
+        // Check for stack to be non empty.
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, UNIQUE_DATA, ctx.unique().getText(), ENTRY);
+
+        Parsable tmpData = listener.getParsedDataStack().peek();
+        if (listener.getParsedDataStack().peek() instanceof YangList) {
+            YangList yangList = (YangList) tmpData;
+            String tmpUniqueValue = removeQuotesAndHandleConcat(ctx.unique().getText());
+
+            if (tmpUniqueValue.contains(" ")) {
+                String[] uniqueValues = tmpUniqueValue.split(" ");
+                for (String uniqueValue : uniqueValues) {
+                    try {
+                        yangList.addUnique(uniqueValue);
+                    } catch (DataModelException e) {
+                        throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
+                                UNIQUE_DATA,
+                                ctx.unique().getText(), ENTRY, e.getMessage()));
+                    }
+                }
+            } else {
+                try {
+                    yangList.addUnique(tmpUniqueValue);
+                } catch (DataModelException e) {
+                    throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, UNIQUE_DATA,
+                            ctx.unique().getText(), ENTRY, e.getMessage()));
+                }
+            }
+        } else {
+            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, UNIQUE_DATA, ctx.unique().getText(),
+                    ENTRY));
+        }
+    }
+}
\ No newline at end of file
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java
index 2240c16..6e27a1b 100644
--- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/UsesListener.java
@@ -137,6 +137,7 @@
             YangUses usesNode = getYangUsesNode(JAVA_GENERATION);
             YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.string().getText(), USES_DATA, ctx);
             usesNode.setNodeIdentifier(nodeIdentifier);
+            usesNode.setCurrentGroupingDepth(listener.getGroupingDepth());
             YangNode curNode = (YangNode) curData;
 
             try {