[ONOS-4351][ONOS-4524] Augment linking and defect fixed.

Change-Id: I7c8e8c90579eea4631e014c4906a543a3c249427
diff --git a/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/AugmentJavaFileNameGenUtil.java b/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/AugmentJavaFileNameGenUtil.java
deleted file mode 100644
index 730923a..0000000
--- a/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/AugmentJavaFileNameGenUtil.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.parserutils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
-
-import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getCapitalCase;
-
-/**
- * Represents a utility which provides valid name for generated java file for augment node.
- */
-public final class AugmentJavaFileNameGenUtil {
-
-    /**
-     * Prefix to be added to generated java file for augment node.
-     */
-    private static final String AUGMENTED = "Augmented";
-
-    /**
-     * The number of time augment has updated the same target node in same module/submodule.
-     */
-    private static int occurrenceCount = 1;
-
-    /**
-     * List of names for generated augment java file.
-     */
-    private static List<String> augmentJavaFileNameList = new ArrayList<>();
-
-    private static final int ONE = 1;
-    private static final int TWO = 2;
-    private static final int ZERO = 0;
-
-    /**
-     * Creates an instance of augment java file name generator utility.
-     */
-    private AugmentJavaFileNameGenUtil() {
-    }
-
-    /**
-     * Sets the augment java file name list.
-     *
-     * @param nameList name list
-     */
-    private static void setAugmentJavaFileNameList(List<String> nameList) {
-        augmentJavaFileNameList = nameList;
-    }
-
-    /**
-     * Returns augment java file name list.
-     *
-     * @return augment java file name list
-     */
-    public static List<String> getAugmentJavaFileNameList() {
-        return augmentJavaFileNameList;
-    }
-
-    /**
-     * Sets occurrence count.
-     *
-     * @param occurrence occurrence count
-     */
-    private static void setOccurrenceCount(int occurrence) {
-        occurrenceCount = occurrence;
-    }
-
-    /**
-     * Returns occurrence count.
-     *
-     * @return occurrence count
-     */
-    private static int getOccurrenceCount() {
-        return occurrenceCount;
-    }
-
-    /**
-     * Creates a name identifier for augment.
-     *
-     * @param nodeId node identifier
-     * @param isPrefix if prefix is present or it is not equals to parent's prefix
-     * @return valid name for augment
-     */
-    public static String createValidNameForAugment(YangNodeIdentifier nodeId, boolean isPrefix) {
-        getAugmentJavaFileNameList().add(createName(nodeId, isPrefix));
-        setAugmentJavaFileNameList(getAugmentJavaFileNameList());
-        return getAugmentJavaFileNameList().get(getAugmentJavaFileNameList().size() - 1);
-    }
-
-    /**
-     * Creates name for the current augment file.
-     *
-     * @param nodeId node identifier
-     * @param isPrefix if prefix is present or it is not equals to parent's prefix
-     */
-    private static String createName(YangNodeIdentifier nodeId, boolean isPrefix) {
-        if (isPrefix) {
-            return AUGMENTED + getCapitalCase(nodeId.getPrefix()) + getCapitalCase(nodeId.getName());
-        } else {
-            return AUGMENTED + getCapitalCase(nodeId.getName());
-        }
-    }
-
-    /**
-     * Updates occurrence count of augment.
-     */
-    public static void updateOccurenceCount() {
-        int count = getOccurrenceCount();
-        count++;
-        setOccurrenceCount(count);
-    }
-
-    /**
-     * Updates the list of name when augment has occurred multiple times to update the same target node
-     * and returns a valid name for augment node's generated java file.
-     *
-     * @param nodeId YANG node identifier
-     * @param isPrefix true if a prefix is present and it is not equals to parents prefix
-     * @return valid name for augment node
-     */
-    public static String updateNameWhenHasMultipleOuccrrence(YangNodeIdentifier nodeId, boolean isPrefix) {
-        String name = "";
-        updateOccurenceCount();
-
-        if (getOccurrenceCount() == TWO) {
-            String previousAugmentsName = getAugmentJavaFileNameList().get(getAugmentJavaFileNameList().size() - ONE);
-            getAugmentJavaFileNameList().remove(ZERO);
-            getAugmentJavaFileNameList().add(previousAugmentsName + ONE);
-            //TODO: update when already contains the name.
-            name = createName(nodeId, isPrefix) + TWO;
-        } else {
-            name = createName(nodeId, isPrefix) + getOccurrenceCount();
-        }
-        getAugmentJavaFileNameList().add(name);
-        return name;
-    }
-
-    /**
-     * Resets occurrence count to one.
-     */
-    public static void clearOccurrenceCount() {
-        setOccurrenceCount(ONE);
-    }
-
-}
diff --git a/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/AugmentListenerUtil.java b/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/AugmentListenerUtil.java
new file mode 100644
index 0000000..764cef4
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/AugmentListenerUtil.java
@@ -0,0 +1,309 @@
+/*
+ * 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.parserutils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onosproject.yangutils.datamodel.CollisionDetector;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+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.translator.tojava.utils.JavaIdentifierSyntax.getCapitalCase;
+import static org.onosproject.yangutils.utils.YangConstructType.AUGMENT_DATA;
+
+/**
+ * Represents a utility which provides listener utilities augment node.
+ */
+public final class AugmentListenerUtil {
+
+    /**
+     * Prefix to be added to generated java file for augment node.
+     */
+    private static final String AUGMENTED = "Augmented";
+
+    /**
+     * The number of time augment has updated the same target node in same module/submodule.
+     */
+    private static int occurrenceCount = 1;
+
+    /**
+     * List of names for augment's generated java file.
+     */
+    private static List<String> augmentJavaFileNameList = new ArrayList<>();
+
+    private static final int ONE = 1;
+    private static final int TWO = 2;
+    private static final int ZERO = 0;
+
+    /**
+     * Creates an instance of augment java file name generator utility.
+     */
+    private AugmentListenerUtil() {
+    }
+
+    /**
+     * Sets the augment java file name list.
+     *
+     * @param nameList name list
+     */
+    private static void setAugmentJavaFileNameList(List<String> nameList) {
+        augmentJavaFileNameList = nameList;
+    }
+
+    /**
+     * Returns augment java file name list.
+     *
+     * @return augment java file name list
+     */
+    public static List<String> getAugmentJavaFileNameList() {
+        return augmentJavaFileNameList;
+    }
+
+    /**
+     * Sets occurrence count.
+     *
+     * @param occurrence occurrence count
+     */
+    private static void setOccurrenceCount(int occurrence) {
+        occurrenceCount = occurrence;
+    }
+
+    /**
+     * Returns occurrence count.
+     *
+     * @return occurrence count
+     */
+    private static int getOccurrenceCount() {
+        return occurrenceCount;
+    }
+
+    /**
+     * Generates name for augment node also detects collision for java file generation of augment node when
+     * augment is updating the same target node in same parent multiple times.
+     *
+     * @param curData parsable data
+     * @param targetNodes list of target nodes
+     * @param listener tree walk listener
+     * @return name for augment node
+     */
+    public static String generateNameForAugmentNode(Parsable curData, List<YangNodeIdentifier> targetNodes,
+            TreeWalkListener listener) {
+
+        String curPrefix = getParentsPrefix((YangNode) curData);
+        YangNodeIdentifier nodeId = targetNodes.get(targetNodes.size() - 1);
+        boolean isPrefix = isPrefixPresent(nodeId, curPrefix);
+        String generateName = createValidNameForAugment(nodeId, isPrefix);
+
+        if (listener.getParsedDataStack().peek() instanceof CollisionDetector) {
+            try {
+                ((CollisionDetector) listener.getParsedDataStack().peek()).detectCollidingChild(generateName,
+                        AUGMENT_DATA);
+            } catch (DataModelException e) {
+                return updateNameWhenHasMultipleOuccrrence(nodeId, isPrefix);
+            }
+        }
+
+        clearOccurrenceCount();
+        return generateName;
+    }
+
+    /**
+     * Creates a name identifier for augment.
+     *
+     * @param nodeId node identifier
+     * @param isPrefix if prefix is present or it is not equals to parent's prefix
+     * @return valid name for augment
+     */
+    public static String createValidNameForAugment(YangNodeIdentifier nodeId, boolean isPrefix) {
+        getAugmentJavaFileNameList().add(createName(nodeId, isPrefix));
+        setAugmentJavaFileNameList(getAugmentJavaFileNameList());
+        return getAugmentJavaFileNameList().get(getAugmentJavaFileNameList().size() - 1);
+    }
+
+    /**
+     * Creates name for the current augment file.
+     *
+     * @param nodeId node identifier
+     * @param isPrefix if prefix is present or it is not equals to parent's prefix
+     */
+    private static String createName(YangNodeIdentifier nodeId, boolean isPrefix) {
+        if (isPrefix) {
+            return AUGMENTED + getCapitalCase(nodeId.getPrefix()) + getCapitalCase(nodeId.getName());
+        } else {
+            return AUGMENTED + getCapitalCase(nodeId.getName());
+        }
+    }
+
+    /**
+     * Updates occurrence count of augment.
+     */
+    private static void updateOccurenceCount() {
+        int count = getOccurrenceCount();
+        count++;
+        setOccurrenceCount(count);
+    }
+
+    /**
+     * Updates the list of name when augment has occurred multiple times to update the same target node
+     * and returns a valid name for augment node's generated java file.
+     *
+     * @param nodeId YANG node identifier
+     * @param isPrefix true if a prefix is present and it is not equals to parents prefix
+     * @return valid name for augment node
+     */
+    public static String updateNameWhenHasMultipleOuccrrence(YangNodeIdentifier nodeId, boolean isPrefix) {
+        String name = "";
+        updateOccurenceCount();
+
+        if (getOccurrenceCount() == TWO) {
+            String previousAugmentsName = getAugmentJavaFileNameList().get(getAugmentJavaFileNameList().size() - ONE);
+            getAugmentJavaFileNameList().remove(ZERO);
+            getAugmentJavaFileNameList().add(previousAugmentsName + ONE);
+            //TODO: update when already contains the name.
+            name = createName(nodeId, isPrefix) + TWO;
+        } else {
+            name = createName(nodeId, isPrefix) + getOccurrenceCount();
+        }
+        getAugmentJavaFileNameList().add(name);
+        return name;
+    }
+
+    /**
+     * Resets occurrence count to one.
+     */
+    public static void clearOccurrenceCount() {
+        setOccurrenceCount(ONE);
+    }
+
+    /**
+     * Returns true if a prefix is present and it is not equals to parents prefix.
+     *
+     * @param nodeId YANG node identifier
+     * @param parentsPrefix parent's prefix
+     * @return true if a prefix is present and it is not equals to parents prefix
+     */
+    private static boolean isPrefixPresent(YangNodeIdentifier nodeId, String parentsPrefix) {
+        return nodeId.getPrefix() != null && nodeId.getPrefix() != parentsPrefix;
+    }
+
+    /**
+     * Validates whether current node in target path is valid or not.
+     *
+     * @param curNode current YANG node
+     * @param targetNodes list of target nodes
+     * @param ctx augment statement context
+     */
+    public static void validateNodeInTargetPath(YangNode curNode, List<YangNodeIdentifier> targetNodes,
+            GeneratedYangParser.AugmentStatementContext ctx) {
+
+        curNode = curNode.getChild();
+        YangNode tempNode = validateCurrentTargetNode(targetNodes, curNode);
+        if (tempNode != null) {
+            switch (tempNode.getNodeType()) {
+                case CONTAINER_NODE:
+                    break;
+                case LIST_NODE:
+                    break;
+                case CHOICE_NODE:
+                    break;
+                case CASE_NODE:
+                    break;
+                case INPUT_NODE:
+                    break;
+                case OUTPUT_NODE:
+                    break;
+                case NOTIFICATION_NODE:
+                    break;
+                default:
+                    throw parserException(ctx);
+            }
+        } else {
+            throw parserException(ctx);
+        }
+    }
+
+    /**
+     * Validates whether nodes in target node list are valid or not.
+     *
+     * @param targetNodeName current target node
+     * @param curNode YANG node
+     * @return true or false
+     */
+    private static YangNode validateCurrentTargetNode(List<YangNodeIdentifier> targetNodes, YangNode curNode) {
+        YangNode tempNode = null;
+        while (curNode != null) {
+            tempNode = curNode;
+            for (int i = 1; i < targetNodes.size(); i++) {
+                if (curNode.getName().equals(targetNodes.get(i).getName())) {
+                    if (curNode.getChild() != null && targetNodes.size() - 1 != i) {
+                        curNode = curNode.getChild();
+                    } else if (curNode.getChild() != null && targetNodes.size() - 1 == i) {
+                        return curNode;
+                    } else if (curNode.getChild() == null && targetNodes.size() - 1 == i) {
+                        return curNode;
+                    } else {
+                        break;
+                    }
+                } else {
+                    curNode = tempNode;
+                    break;
+                }
+            }
+            curNode = curNode.getNextSibling();
+        }
+        return null;
+    }
+
+    /**
+     * Builds parser exception.
+     *
+     * @param ctx augment statement context
+     * @return parser exception
+     */
+    public static ParserException parserException(GeneratedYangParser.AugmentStatementContext ctx) {
+        int line = ctx.getStart().getLine();
+        int charPositionInLine = ctx.getStart().getCharPositionInLine();
+        ParserException exception = new ParserException("invalid target node path.");
+        exception.setLine(line);
+        exception.setCharPosition(charPositionInLine);
+        return exception;
+    }
+
+    /**
+     * Returns parent nodes prefix.
+     *
+     * @param curNode current YANG node
+     * @return parent nodes prefix
+     */
+    public static String getParentsPrefix(YangNode curNode) {
+        String curPrefix = null;
+        if (curNode instanceof YangModule) {
+            curPrefix = ((YangModule) curNode).getPrefix();
+        } else if (curNode instanceof YangSubModule) {
+            curPrefix = ((YangSubModule) curNode).getPrefix();
+        }
+        return curPrefix;
+    }
+}