[ONOS-4350] Inter Jar dependency implementation and code restructuring.
Change-Id: Iacac75e4187aed93ce1754c170a9c19707e5b8c3
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/AugmentListenerUtil.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/AugmentListenerUtil.java
new file mode 100644
index 0000000..1b2009e
--- /dev/null
+++ b/utils/yangutils/plugin/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.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.AUGMENT_DATA;
+import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getCapitalCase;
+
+/**
+ * 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 targetNodes 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;
+ }
+}
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerCollisionDetector.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerCollisionDetector.java
new file mode 100644
index 0000000..632f50d
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerCollisionDetector.java
@@ -0,0 +1,73 @@
+/*
+ * 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 org.onosproject.yangutils.datamodel.CollisionDetector;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.datamodel.utils.YangConstructType;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+
+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;
+
+/**
+ * Represents the detector of YANG construct collision in a YANG file.
+ */
+public final class ListenerCollisionDetector {
+
+ /**
+ * Creates a new listener collision.
+ */
+ private ListenerCollisionDetector() {
+ }
+
+ /**
+ * Detects that the identifiers of all these child nodes must be unique
+ * within all cases in a choice.
+ *
+ * @param listener listener's object
+ * @param line line of identifier in YANG file, required for error
+ * reporting
+ * @param charPosition character position of identifier in YANG file,
+ * required for error reporting
+ * @param identifierName name for which uniqueness is to be detected
+ * @param constructType type of YANG construct for which collision check is
+ * to be performed
+ * @throws ParserException if identifier is not unique
+ */
+ public static void detectCollidingChildUtil(TreeWalkListener listener, int line, int charPosition,
+ String identifierName, YangConstructType constructType)
+ throws ParserException {
+
+ if (listener.getParsedDataStack().peek() instanceof CollisionDetector) {
+ try {
+ ((CollisionDetector) listener.getParsedDataStack().peek()).detectCollidingChild(
+ identifierName, constructType);
+ } catch (DataModelException e) {
+ ParserException parserException = new ParserException(e.getMessage());
+ parserException.setLine(line);
+ parserException.setCharPosition(charPosition);
+ throw parserException;
+ }
+ } else {
+ throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, constructType, identifierName,
+ EXIT));
+ }
+ }
+}
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorLocation.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorLocation.java
new file mode 100644
index 0000000..c1c2888
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorLocation.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+/**
+ * Represents listener error location.
+ */
+public enum ListenerErrorLocation {
+ /**
+ * Represents that the error location is before processing.
+ */
+ ENTRY(),
+
+ /**
+ * Represents that the error location is before processing.
+ */
+ EXIT();
+
+ /**
+ * Returns the message corresponding to listener error location.
+ *
+ * @param errorLocation enum value for type of error
+ * @return message corresponding to listener error location
+ */
+ public static String getErrorLocationMessage(ListenerErrorLocation errorLocation) {
+
+ switch (errorLocation) {
+ case ENTRY:
+ return "before";
+ case EXIT:
+ return "after";
+ default:
+ return "during";
+ }
+ }
+}
\ No newline at end of file
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorMessageConstruction.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorMessageConstruction.java
new file mode 100644
index 0000000..15b2170
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorMessageConstruction.java
@@ -0,0 +1,92 @@
+/*
+ * 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 static org.onosproject.yangutils.datamodel.utils.YangConstructType.getYangConstructType;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.getErrorLocationMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.getErrorType;
+
+import org.onosproject.yangutils.datamodel.utils.YangConstructType;
+
+/**
+ * Represents a utility to help construct detailed error message.
+ */
+public final class ListenerErrorMessageConstruction {
+
+ /**
+ * Creates a object of listen error message.
+ */
+ private ListenerErrorMessageConstruction() {
+ }
+
+ /**
+ * Constructs message for error with extended information and returns the
+ * same.
+ *
+ * @param errorType error type needs to be set in error message
+ * @param yangConstructType type of parsable data in which error occurred
+ * @param parsableDataTypeName identifier/string of parsable data type in
+ * which error occurred
+ * @param errorLocation location where error occurred
+ * @param extendedErrorInformation extended error information
+ * @return constructed error message
+ */
+ public static String constructExtendedListenerErrorMessage(ListenerErrorType errorType,
+ YangConstructType yangConstructType,
+ String parsableDataTypeName,
+ ListenerErrorLocation errorLocation,
+ String extendedErrorInformation) {
+ String newErrorMessage;
+ newErrorMessage = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
+ errorLocation)
+ + "\n"
+ + "Error Information: "
+ + extendedErrorInformation;
+ return newErrorMessage;
+ }
+
+ /**
+ * Constructs message for error during listener based tree walk and returns
+ * the same.
+ *
+ * @param errorType error type needs to be set in error message
+ * @param yangConstructType type of parsable data in which error occurred
+ * @param parsableDataTypeName identifier/string of parsable data type in
+ * which error occurred
+ * @param errorLocation location where error occurred
+ * @return constructed error message
+ */
+ public static String constructListenerErrorMessage(ListenerErrorType errorType,
+ YangConstructType yangConstructType,
+ String parsableDataTypeName,
+ ListenerErrorLocation errorLocation) {
+
+ String errorMessage;
+
+ errorMessage = "Internal parser error detected: " + getErrorType(errorType) + " "
+ + getYangConstructType(yangConstructType);
+
+ if (!parsableDataTypeName.isEmpty()) {
+ errorMessage = errorMessage + " \"" + parsableDataTypeName + "\" ";
+ } else {
+ errorMessage = errorMessage + " ";
+
+ }
+ errorMessage = errorMessage + getErrorLocationMessage(errorLocation) + " processing.";
+ return errorMessage;
+ }
+}
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorType.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorType.java
new file mode 100644
index 0000000..f1cb284
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorType.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.parserutils;
+
+/**
+ * Represents listener error type.
+ */
+public enum ListenerErrorType {
+ /**
+ * Represents the parent holder in parsable stack for given YANG construct
+ * is invalid.
+ */
+ INVALID_HOLDER(),
+
+ /**
+ * Represents the parent holder in parsable stack for given YANG construct
+ * is missing.
+ */
+ MISSING_HOLDER(),
+
+ /**
+ * Represents the current holder in parsable stack for given YANG construct
+ * is missing.
+ */
+ MISSING_CURRENT_HOLDER(),
+
+ /**
+ * Represents that the child in parsable stack for given YANG construct is
+ * invalid.
+ */
+ INVALID_CHILD(),
+
+ /**
+ * Represents that the cardinality for given YANG construct is invalid.
+ */
+ INVALID_CARDINALITY(),
+
+ /**
+ * Represents that the entry is duplicate.
+ */
+ DUPLICATE_ENTRY(),
+
+ /**
+ * Represents that the content is invalid.
+ */
+ INVALID_CONTENT(),
+
+ /**
+ * Represents that the identifier collision is detected.
+ */
+ IDENTIFIER_COLLISION(),
+
+ /**
+ * Represents that some of earlier parsed data is not handled correctly.
+ */
+ UNHANDLED_PARSED_DATA();
+
+ /**
+ * Returns the message corresponding to listener error type.
+ *
+ * @param errorType enum value for type of error
+ * @return message corresponding to listener error type
+ */
+ public static String getErrorType(ListenerErrorType errorType) {
+
+ switch (errorType) {
+ case INVALID_HOLDER:
+ return "Invalid holder for";
+ case MISSING_HOLDER:
+ return "Missing holder at";
+ case MISSING_CURRENT_HOLDER:
+ return "Missing";
+ case INVALID_CHILD:
+ return "Invalid child in";
+ case INVALID_CARDINALITY:
+ return "Invalid cardinality in";
+ case DUPLICATE_ENTRY:
+ return "Duplicate";
+ case INVALID_CONTENT:
+ return "Invalid content in";
+ case IDENTIFIER_COLLISION:
+ return "Identifier collision detected for";
+ case UNHANDLED_PARSED_DATA:
+ return "Unhandled parsed data at";
+ default:
+ return "Problem in";
+ }
+ }
+}
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
new file mode 100644
index 0000000..d05c8d0
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
@@ -0,0 +1,376 @@
+/*
+ * 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.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+import org.onosproject.yangutils.datamodel.utils.YangConstructType;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+
+import static org.onosproject.yangutils.utils.UtilConstants.ADD;
+import static org.onosproject.yangutils.utils.UtilConstants.SPACE;
+import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
+import static org.onosproject.yangutils.utils.UtilConstants.COLON;
+import static org.onosproject.yangutils.utils.UtilConstants.CARET;
+import static org.onosproject.yangutils.utils.UtilConstants.CURRENTLY_UNSUPPORTED;
+import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
+import static org.onosproject.yangutils.utils.UtilConstants.HYPHEN;
+import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
+import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
+import static org.onosproject.yangutils.utils.UtilConstants.FALSE;
+import static org.onosproject.yangutils.utils.UtilConstants.YANG_FILE_ERROR;
+import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
+import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
+import static org.onosproject.yangutils.utils.UtilConstants.INSTANCE_IDENTIFIER;
+
+/**
+ * Represents an utility for listener.
+ */
+public final class ListenerUtil {
+
+ private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
+ private static final String DATE_PATTERN = "[0-9]{4}-([0-9]{2}|[0-9])-([0-9]{2}|[0-9])";
+ private static final String NON_NEGATIVE_INTEGER_PATTERN = "[0-9]+";
+ private static final Pattern INTEGER_PATTERN = Pattern.compile("[-][0-9]+|[0-9]+");
+ private static final String XML = "xml";
+ private static final String ONE = "1";
+ private static final int IDENTIFIER_LENGTH = 64;
+ private static final String DATE_FORMAT = "yyyy-MM-dd";
+
+ /**
+ * Creates a new listener util.
+ */
+ private ListenerUtil() {
+ }
+
+ /**
+ * Removes doubles quotes and concatenates if string has plus symbol.
+ *
+ * @param yangStringData string from yang file
+ * @return concatenated string after removing double quotes
+ */
+ public static String removeQuotesAndHandleConcat(String yangStringData) {
+
+ yangStringData = yangStringData.replace("\"", EMPTY_STRING);
+ String[] tmpData = yangStringData.split(Pattern.quote(ADD));
+ StringBuilder builder = new StringBuilder();
+ for (String yangString : tmpData) {
+ builder.append(yangString);
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Validates identifier and returns concatenated string if string contains plus symbol.
+ *
+ * @param identifier 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 concatenated string after removing double quotes
+ */
+ public static String getValidIdentifier(String identifier, YangConstructType yangConstruct, ParserRuleContext ctx) {
+
+ String identifierString = removeQuotesAndHandleConcat(identifier);
+ ParserException parserException;
+
+ if (identifierString.length() > IDENTIFIER_LENGTH) {
+ parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is " +
+ "greater than 64 characters.");
+ } else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
+ parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is not " +
+ "valid.");
+ } else if (identifierString.toLowerCase().startsWith(XML)) {
+ parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " identifier " + identifierString +
+ " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
+ } else {
+ return identifierString;
+ }
+
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+
+ /**
+ * Validates the revision date.
+ *
+ * @param dateToValidate input revision date
+ * @return validation result, true for success, false for failure
+ */
+ public static boolean isDateValid(String dateToValidate) {
+ if (dateToValidate == null || !dateToValidate.matches(DATE_PATTERN)) {
+ return false;
+ }
+
+ SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+ sdf.setLenient(false);
+
+ try {
+ //if not valid, it will throw ParseException
+ sdf.parse(dateToValidate);
+ } catch (ParseException e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Validates YANG version.
+ *
+ * @param ctx version context object of the grammar rule
+ * @return valid version
+ */
+ public static byte getValidVersion(GeneratedYangParser.YangVersionStatementContext ctx) {
+
+ String value = removeQuotesAndHandleConcat(ctx.version().getText());
+ if (!value.equals(ONE)) {
+ ParserException parserException = new ParserException("YANG file error: Input version not supported");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+
+ return Byte.valueOf(value);
+ }
+
+ /**
+ * Validates non negative integer value.
+ *
+ * @param integerValue integer to be validated
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx context object of the grammar rule
+ * @return valid non negative integer value
+ */
+ public static int getValidNonNegativeIntegerValue(String integerValue, YangConstructType yangConstruct,
+ ParserRuleContext ctx) {
+
+ String value = removeQuotesAndHandleConcat(integerValue);
+ if (!value.matches(NON_NEGATIVE_INTEGER_PATTERN)) {
+ ParserException parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
+ "valid.");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+
+ int valueInInteger;
+ try {
+ valueInInteger = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ ParserException parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
+ "valid.");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ return valueInInteger;
+ }
+
+ /**
+ * Validates integer value.
+ *
+ * @param integerValue integer to be validated
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx context object of the grammar rule
+ * @return valid integer value
+ */
+ public static int getValidIntegerValue(String integerValue, YangConstructType yangConstruct,
+ ParserRuleContext ctx) {
+
+ String value = removeQuotesAndHandleConcat(integerValue);
+ if (!INTEGER_PATTERN.matcher(value).matches()) {
+ ParserException parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
+ "valid.");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+
+ int valueInInteger;
+ try {
+ valueInInteger = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ ParserException parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
+ "valid.");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ return valueInInteger;
+ }
+
+ /**
+ * Validates boolean value.
+ *
+ * @param booleanValue value to be validated
+ * @param yangConstruct yang construct for creating error message
+ * @param ctx context object of the grammar rule
+ * @return boolean value either true or false
+ */
+ public static boolean getValidBooleanValue(String booleanValue, YangConstructType yangConstruct,
+ ParserRuleContext ctx) {
+
+ String value = removeQuotesAndHandleConcat(booleanValue);
+ if (value.equals(TRUE)) {
+ return true;
+ } else if (value.equals(FALSE)) {
+ return false;
+ } else {
+ ParserException parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
+ "valid.");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ }
+
+ /**
+ * Sets current date and makes it in usable format for revision.
+ *
+ * @return usable current date format for revision
+ */
+ public static String setCurrentDateForRevision() {
+
+ Calendar date = Calendar.getInstance();
+ SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+ String dateForRevision = dateFormat.format(date.getTime()).replaceAll(SLASH, HYPHEN).replaceAll(SPACE,
+ 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();
+ checkForUnsupportedTypes(tmpData[0], yangConstruct, ctx);
+ 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;
+ }
+ }
+
+ /**
+ * Checks whether the type is an unsupported type.
+ *
+ * @param typeName name of the type
+ * @param yangConstruct yang construct to check if it is type
+ * @param ctx yang construct's context to get the line number and character position
+ */
+ private static void checkForUnsupportedTypes(String typeName,
+ YangConstructType yangConstruct, ParserRuleContext ctx) {
+
+ if (yangConstruct == YangConstructType.TYPE_DATA) {
+ if (typeName.equalsIgnoreCase(LEAFREF)) {
+ handleUnsupportedYangConstruct(YangConstructType.LEAFREF_DATA,
+ ctx, CURRENTLY_UNSUPPORTED);
+ } else if (typeName.equalsIgnoreCase(IDENTITYREF)) {
+ handleUnsupportedYangConstruct(YangConstructType.IDENTITYREF_DATA,
+ ctx, CURRENTLY_UNSUPPORTED);
+ } else if (typeName.equalsIgnoreCase(INSTANCE_IDENTIFIER)) {
+ handleUnsupportedYangConstruct(YangConstructType.INSTANCE_IDENTIFIER_DATA,
+ ctx, CURRENTLY_UNSUPPORTED);
+ }
+ }
+ }
+
+ /**
+ * Checks and return valid absolute schema node id.
+ *
+ * @param argumentString string from yang file
+ * @param yangConstructType yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
+ * @return target nodes list of absolute schema node id
+ */
+ public static List<YangNodeIdentifier> getValidAbsoluteSchemaNodeId(String argumentString,
+ YangConstructType yangConstructType, ParserRuleContext ctx) {
+
+ List<YangNodeIdentifier> targetNodes = new LinkedList<>();
+ YangNodeIdentifier yangNodeIdentifier;
+ String tmpSchemaNodeId = removeQuotesAndHandleConcat(argumentString);
+
+ // absolute-schema-nodeid = 1*("/" node-identifier)
+ if (!tmpSchemaNodeId.startsWith(SLASH)) {
+ ParserException parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(yangConstructType) + " name " + argumentString +
+ "is not valid");
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ String[] tmpData = tmpSchemaNodeId.replaceFirst(CARET + SLASH, EMPTY_STRING).split(SLASH);
+ for (String nodeIdentifiers : tmpData) {
+ yangNodeIdentifier = getValidNodeIdentifier(nodeIdentifiers, yangConstructType, ctx);
+ targetNodes.add(yangNodeIdentifier);
+ }
+ return targetNodes;
+ }
+
+ /**
+ * Throws parser exception for unsupported YANG constructs.
+ *
+ * @param yangConstructType yang construct for creating error message
+ * @param ctx yang construct's context to get the line number and character position
+ * @param errorInfo error information
+ */
+ public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
+ ParserRuleContext ctx, String errorInfo) {
+ ParserException parserException = new ParserException(YANG_FILE_ERROR
+ + QUOTES + YangConstructType.getYangConstructType(yangConstructType) + QUOTES
+ + errorInfo);
+ parserException.setLine(ctx.getStart().getLine());
+ parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+}
\ No newline at end of file
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerValidation.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerValidation.java
new file mode 100644
index 0000000..f5e98d0
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerValidation.java
@@ -0,0 +1,237 @@
+/*
+ * 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.Iterator;
+import java.util.List;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.utils.Parsable;
+import org.onosproject.yangutils.datamodel.utils.YangConstructType;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+
+import static org.onosproject.yangutils.datamodel.utils.YangConstructType.getYangConstructType;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
+
+/**
+ * Represents a utility to carry out listener validation.
+ */
+public final class ListenerValidation {
+
+ /**
+ * Creates a new listener validation.
+ */
+ private ListenerValidation() {
+ }
+
+ /**
+ * Checks parsed data stack is not empty.
+ *
+ * @param listener Listener's object
+ * @param errorType error type needs to be set in error message
+ * @param yangConstructType type of parsable data in which error occurred
+ * @param parsableDataTypeName name of parsable data type in which error
+ * occurred
+ * @param errorLocation location where error occurred
+ */
+ public static void checkStackIsNotEmpty(TreeWalkListener listener, ListenerErrorType errorType,
+ YangConstructType yangConstructType, String parsableDataTypeName,
+ ListenerErrorLocation errorLocation) {
+
+ if (listener.getParsedDataStack().empty()) {
+ /*
+ * If stack is empty it indicates error condition, value of
+ * parsableDataTypeName will be null in case there is no name
+ * attached to parsable data type.
+ */
+ String message = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
+ errorLocation);
+ throw new ParserException(message);
+ }
+ }
+
+ /**
+ * Checks parsed data stack is empty.
+ *
+ * @param listener Listener's object
+ * @param errorType error type needs to be set in error message
+ * @param yangConstructType type of parsable data in which error occurred
+ * @param parsableDataTypeName name of parsable data type in which error
+ * occurred
+ * @param errorLocation location where error occurred
+ */
+ public static void checkStackIsEmpty(TreeWalkListener listener, ListenerErrorType errorType,
+ YangConstructType yangConstructType, String parsableDataTypeName,
+ ListenerErrorLocation errorLocation) {
+
+ if (!listener.getParsedDataStack().empty()) {
+ /*
+ * If stack is empty it indicates error condition, value of
+ * parsableDataTypeName will be null in case there is no name
+ * attached to parsable data type.
+ */
+ String message = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
+ errorLocation);
+ throw new ParserException(message);
+ }
+ }
+
+ /**
+ * Returns parent node config value, if top node does not specify a config
+ * statement then default value true is returned.
+ *
+ * @param listener listener's object
+ * @return true/false parent's config value
+ */
+ public static boolean getParentNodeConfig(TreeWalkListener listener) {
+
+ YangNode parentNode;
+ Parsable curData = listener.getParsedDataStack().peek();
+ if (curData instanceof YangNode) {
+ parentNode = ((YangNode) curData).getParent();
+ if (parentNode instanceof YangContainer) {
+ return ((YangContainer) parentNode).isConfig();
+ } else if (parentNode instanceof YangList) {
+ return ((YangList) parentNode).isConfig();
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks if a rule occurrences is as per the expected YANG grammar's
+ * cardinality.
+ *
+ * @param childContext child's context
+ * @param yangChildConstruct child construct for whom cardinality is to be
+ * validated
+ * @param yangParentConstruct parent construct
+ * @param parentName parent name
+ * @throws ParserException exception if cardinality check fails
+ */
+ public static void validateCardinalityMaxOne(List<?> childContext, YangConstructType yangChildConstruct,
+ YangConstructType yangParentConstruct, String parentName)
+ throws ParserException {
+
+ if (!childContext.isEmpty() && childContext.size() != 1) {
+ ParserException parserException = new ParserException("YANG file error: \""
+ + getYangConstructType(yangChildConstruct) + "\" is defined more than once in \""
+ + getYangConstructType(yangParentConstruct) + " " + parentName + "\".");
+
+ Iterator<?> context = childContext.iterator();
+ parserException.setLine(((ParserRuleContext) context.next()).getStart().getLine());
+ parserException.setCharPosition(((ParserRuleContext) context.next()).getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ }
+
+ /**
+ * Checks if a rule occurrences is exactly 1.
+ *
+ * @param childContext child's context
+ * @param yangChildConstruct child construct for whom cardinality is to be
+ * validated
+ * @param yangParentConstruct parent construct
+ * @param parentName parent name
+ * @param parentContext parents's context
+ * @throws ParserException exception if cardinality check fails
+ */
+ public static void validateCardinalityEqualsOne(List<?> childContext, YangConstructType yangChildConstruct,
+ YangConstructType yangParentConstruct, String parentName,
+ ParserRuleContext parentContext)
+ throws ParserException {
+
+ if (childContext.isEmpty()) {
+ ParserException parserException = new ParserException("YANG file error: Missing \""
+ + getYangConstructType(yangChildConstruct) + "\" in \"" + getYangConstructType(yangParentConstruct)
+ + " " + parentName + "\".");
+ parserException.setLine(parentContext.getStart().getLine());
+ parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
+ throw parserException;
+ } else if (!childContext.isEmpty() && childContext.size() != 1) {
+ Iterator<?> childcontext = childContext.iterator();
+ ParserException parserException = new ParserException("YANG file error: \""
+ + getYangConstructType(yangChildConstruct) + "\" is present more than once in \""
+ + getYangConstructType(yangParentConstruct) + " " + parentName + "\".");
+ parserException.setLine(((ParserRuleContext) childcontext.next()).getStart().getLine());
+ parserException.setCharPosition(((ParserRuleContext) childcontext.next()).getStart()
+ .getCharPositionInLine());
+ throw parserException;
+ }
+ }
+
+ /**
+ * Checks if a rule occurrences is minimum 1.
+ *
+ * @param childContext child's context
+ * @param yangChildConstruct child construct for whom cardinality is to be
+ * validated
+ * @param yangParentConstruct parent construct
+ * @param parentName parent name
+ * @param parentContext parents's context
+ * @throws ParserException exception if cardinality check fails
+ */
+ public static void validateCardinalityNonZero(List<?> childContext, YangConstructType yangChildConstruct,
+ YangConstructType yangParentConstruct, String parentName,
+ ParserRuleContext parentContext)
+ throws ParserException {
+
+ if (childContext.isEmpty()) {
+ ParserException parserException = new ParserException("YANG file error: Missing \""
+ + getYangConstructType(yangChildConstruct) + "\" in \"" + getYangConstructType(yangParentConstruct)
+ + " " + parentName + "\".");
+
+ parserException.setLine(parentContext.getStart().getLine());
+ parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ }
+
+ /**
+ * Checks if a either of one construct occurrence.
+ *
+ * @param child1Context first optional child's context
+ * @param yangChild1Construct first child construct for whom cardinality is
+ * to be validated
+ * @param child2Context second optional child's context
+ * @param yangChild2Construct second child construct for whom cardinality is
+ * to be validated
+ * @param yangParentConstruct parent construct
+ * @param parentName parent name
+ * @throws ParserException exception if cardinality check fails
+ */
+ public static void validateMutuallyExclusiveChilds(List<?> child1Context, YangConstructType yangChild1Construct,
+ List<?> child2Context, YangConstructType yangChild2Construct,
+ YangConstructType yangParentConstruct, String parentName)
+ throws ParserException {
+
+ if (!child1Context.isEmpty() && !child2Context.isEmpty()) {
+ ParserException parserException = new ParserException("YANG file error: \""
+ + getYangConstructType(yangChild1Construct) + "\" & \"" + getYangConstructType(yangChild2Construct)
+ + "\" should be mutually exclusive in \"" + getYangConstructType(yangParentConstruct) + " "
+ + parentName + "\".");
+
+ parserException.setLine(((ParserRuleContext) child2Context).getStart().getLine());
+ parserException.setCharPosition(((ParserRuleContext) child2Context).getStart().getCharPositionInLine());
+ throw parserException;
+ }
+ }
+}
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ParseTreeErrorListener.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ParseTreeErrorListener.java
new file mode 100644
index 0000000..af81d6f
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ParseTreeErrorListener.java
@@ -0,0 +1,41 @@
+/*
+ * 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 org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+
+/**
+ * Represent the parse tree error listener.
+ * By default, ANTLR sends all errors to standard error, this is changed by
+ * providing this new implementation of interface ANTLRErrorListener. The
+ * interface has a syntaxError() method that applies to both lexer and parser.
+ */
+public class ParseTreeErrorListener extends BaseErrorListener {
+
+ @Override
+ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
+ String msg, RecognitionException e) {
+
+ ParserException parserException = new ParserException(msg);
+ parserException.setLine(line);
+ parserException.setCharPosition(charPositionInLine);
+ throw parserException;
+ }
+}
\ No newline at end of file
diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/package-info.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/package-info.java
new file mode 100644
index 0000000..9eafb00
--- /dev/null
+++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provide common utils for parser implementation.
+ */
+package org.onosproject.yangutils.parser.impl.parserutils;
\ No newline at end of file