[ONOS-4063 to 68] Intra YANG file Linking Implementation and Intra YANG file Linking Framework

Change-Id: I06e602c351ab54178bf90b8676af71a70e42371f
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BelongsToListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BelongsToListener.java
index 92b1ee9..12c292a 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BelongsToListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BelongsToListener.java
@@ -23,13 +23,13 @@
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 import org.onosproject.yangutils.parser.impl.TreeWalkListener;
 
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
 import static org.onosproject.yangutils.utils.YangConstructType.BELONGS_TO_DATA;
 
@@ -119,6 +119,7 @@
             case SUB_MODULE_DATA: {
                 YangSubModule subModule = (YangSubModule) tmpNode;
                 subModule.setBelongsTo((YangBelongsTo) tmpBelongstoNode);
+                subModule.setPrefix(subModule.getBelongsTo().getPrefix());
                 break;
             }
             default:
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ImportListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ImportListener.java
index f34bd30..63dfbc7 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ImportListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ImportListener.java
@@ -113,12 +113,12 @@
             switch (tmpNode.getYangConstructType()) {
             case MODULE_DATA: {
                 YangModule module = (YangModule) tmpNode;
-                module.addImportedInfo((YangImport) tmpImportNode);
+                module.addToImportList((YangImport) tmpImportNode);
                 break;
             }
             case SUB_MODULE_DATA: {
                 YangSubModule subModule = (YangSubModule) tmpNode;
-                subModule.addImportedInfo((YangImport) tmpImportNode);
+                subModule.addToImportList((YangImport) tmpImportNode);
                 break;
             }
             default:
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IncludeListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IncludeListener.java
index b9325da..9cd6a26 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IncludeListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IncludeListener.java
@@ -24,13 +24,13 @@
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 import org.onosproject.yangutils.parser.impl.TreeWalkListener;
 
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
 import static org.onosproject.yangutils.utils.YangConstructType.INCLUDE_DATA;
 
@@ -112,12 +112,12 @@
             switch (tmpNode.getYangConstructType()) {
             case MODULE_DATA: {
                 YangModule module = (YangModule) tmpNode;
-                module.addIncludedInfo((YangInclude) tmpIncludeNode);
+                module.addToIncludeList((YangInclude) tmpIncludeNode);
                 break;
             }
             case SUB_MODULE_DATA: {
                 YangSubModule subModule = (YangSubModule) tmpNode;
-                subModule.addIncludedInfo((YangInclude) tmpIncludeNode);
+                subModule.addToIncludeList((YangInclude) tmpIncludeNode);
                 break;
             }
             default:
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ModuleListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ModuleListener.java
index ef302be..51f8364 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ModuleListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ModuleListener.java
@@ -16,8 +16,10 @@
 
 package org.onosproject.yangutils.parser.impl.listeners;
 
+import org.onosproject.yangutils.datamodel.HasResolutionInfo;
 import org.onosproject.yangutils.datamodel.YangModule;
 import org.onosproject.yangutils.datamodel.YangRevision;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 import org.onosproject.yangutils.parser.impl.TreeWalkListener;
@@ -113,5 +115,13 @@
             throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, MODULE_DATA,
                     ctx.identifier().getText(), EXIT));
         }
+        try {
+            ((HasResolutionInfo) listener.getParsedDataStack().peek()).resolveSelfFileLinking();
+        } catch (DataModelException e) {
+            ParserException parserException = new ParserException(e.getMessage());
+            parserException.setLine(e.getLineNumber());
+            parserException.setCharPosition(e.getCharPositionInLine());
+            throw parserException;
+        }
     }
 }
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/SubModuleListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/SubModuleListener.java
index eb16253..225aff5 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/SubModuleListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/SubModuleListener.java
@@ -16,8 +16,10 @@
 
 package org.onosproject.yangutils.parser.impl.listeners;
 
+import org.onosproject.yangutils.datamodel.HasResolutionInfo;
 import org.onosproject.yangutils.datamodel.YangRevision;
 import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 import org.onosproject.yangutils.parser.impl.TreeWalkListener;
@@ -118,5 +120,13 @@
             throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, SUB_MODULE_DATA,
                     ctx.identifier().getText(), EXIT));
         }
+        try {
+            ((HasResolutionInfo) listener.getParsedDataStack().peek()).resolveSelfFileLinking();
+        } catch (DataModelException e) {
+            ParserException parserException = new ParserException(e.getMessage());
+            parserException.setLine(e.getLineNumber());
+            parserException.setCharPosition(e.getCharPositionInLine());
+            throw parserException;
+        }
     }
 }
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 3ca81fb..74e1f0d 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,18 +17,15 @@
 package org.onosproject.yangutils.parser.impl.listeners;
 
 import org.onosproject.yangutils.datamodel.YangContainer;
-import org.onosproject.yangutils.datamodel.YangDataTypes;
-import org.onosproject.yangutils.datamodel.YangDerivedType;
+import org.onosproject.yangutils.datamodel.YangInput;
 import org.onosproject.yangutils.datamodel.YangList;
 import org.onosproject.yangutils.datamodel.YangModule;
 import org.onosproject.yangutils.datamodel.YangNode;
-import org.onosproject.yangutils.datamodel.YangSubModule;
-import org.onosproject.yangutils.datamodel.YangType;
-import org.onosproject.yangutils.datamodel.YangTypeDef;
-import org.onosproject.yangutils.datamodel.YangInput;
-import org.onosproject.yangutils.datamodel.YangOutput;
 import org.onosproject.yangutils.datamodel.YangNotification;
+import org.onosproject.yangutils.datamodel.YangOutput;
 import org.onosproject.yangutils.datamodel.YangRpc;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.Parsable;
 import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
@@ -123,12 +120,8 @@
          * Create a derived type information, the base type must be set in type
          * listener.
          */
-        YangType<YangDerivedType> derivedType = new YangType<YangDerivedType>();
-        derivedType.setDataType(YangDataTypes.DERIVED);
-        derivedType.setDataTypeName(identifier);
-
         YangTypeDef typeDefNode = getYangTypeDefNode(JAVA_GENERATION);
-        typeDefNode.setDerivedType(derivedType);
+        typeDefNode.setName(identifier);
 
         Parsable curData = listener.getParsedDataStack().peek();
 
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
index b000242..6f2f795 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
@@ -16,10 +16,14 @@
 
 package org.onosproject.yangutils.parser.impl.listeners;
 
+import org.onosproject.yangutils.datamodel.ResolutionType;
 import org.onosproject.yangutils.datamodel.YangDataTypes;
-import org.onosproject.yangutils.datamodel.YangDerivedType;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+import org.onosproject.yangutils.datamodel.YangResolutionInfo;
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.YangTypeDef;
 import org.onosproject.yangutils.datamodel.YangUnion;
@@ -28,13 +32,18 @@
 import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+import org.onosproject.yangutils.utils.YangConstructType;
 
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
 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.utils.YangConstructType.TYPE_DATA;
 
@@ -77,12 +86,19 @@
         // Check for stack to be non empty.
         checkStackIsNotEmpty(listener, MISSING_HOLDER, TYPE_DATA, ctx.string().getText(), ENTRY);
 
-        YangDataTypes yangDataTypes = YangDataTypes.getType(ctx.string().getText());
-        YangType<?> type = new YangType();
+        // Validate node identifier.
+        YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.string().getText(), YangConstructType.TYPE_DATA,
+                ctx);
 
-        type.setDataTypeName(ctx.string().getText());
+        // Obtain the YANG data type.
+        YangDataTypes yangDataTypes = YangDataTypes.getType(ctx.string().getText());
+
+        // Create YANG type object and fill the values.
+        YangType<?> type = new YangType();
+        type.setNodeIdentifier(nodeIdentifier);
         type.setDataType(yangDataTypes);
 
+        // Push the type to the stack.
         listener.getParsedDataStack().push(type);
     }
 
@@ -99,24 +115,91 @@
         // Check for stack to be non empty.
         checkStackIsNotEmpty(listener, MISSING_CURRENT_HOLDER, TYPE_DATA, ctx.string().getText(), EXIT);
 
-        Parsable type = listener.getParsedDataStack().pop();
-        if (!(type instanceof YangType)) {
+        Parsable parsableType = listener.getParsedDataStack().pop();
+        if (!(parsableType instanceof YangType)) {
             throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
                     ctx.string().getText(), EXIT));
         }
 
+        YangType<?> type = (YangType<?>) parsableType;
+
         // Check for stack to be non empty.
         checkStackIsNotEmpty(listener, MISSING_HOLDER, TYPE_DATA, ctx.string().getText(), EXIT);
 
+        YangDataTypes yangDataTypes = YangDataTypes.getType(ctx.string().getText());
+
+        int errorLine = ctx.getStart().getLine();
+        int errorPosition = ctx.getStart().getCharPositionInLine();
+
         Parsable tmpData = listener.getParsedDataStack().peek();
         switch (tmpData.getYangConstructType()) {
             case LEAF_DATA:
                 YangLeaf leaf = (YangLeaf) tmpData;
                 leaf.setDataType((YangType<?>) type);
+
+                /*
+                 * If data type is derived, resolution information to be added
+                 * in resolution list.
+                 */
+                if (yangDataTypes == YangDataTypes.DERIVED) {
+                    // Parent YANG node of leaf to be added in resolution information.
+                    Parsable leafData = listener.getParsedDataStack().pop();
+                    Parsable parentNodeOfLeaf = listener.getParsedDataStack().peek();
+                    listener.getParsedDataStack().push(leafData);
+
+                    // Verify parent node of leaf
+                    if (!(parentNodeOfLeaf instanceof YangNode)) {
+                        throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
+                                ctx.string().getText(), EXIT));
+                    }
+
+                    // Get the prefix information
+                    String prefix = ((YangType<?>) type).getPrefix();
+
+                    // Create empty derived info and attach it to type extended info.
+                    YangDerivedInfo<?> yangDerivedInfo = new YangDerivedInfo<>();
+                    ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
+
+                    // Add resolution information to the list
+                    YangResolutionInfo resolutionInfo = new YangResolutionInfo<YangType>(type,
+                            ResolutionType.TYPEDEF_RESOLUTION, (YangNode) parentNodeOfLeaf, prefix, errorLine,
+                            errorPosition);
+                    addToResolutionList(resolutionInfo, ctx);
+                }
                 break;
             case LEAF_LIST_DATA:
                 YangLeafList leafList = (YangLeafList) tmpData;
                 leafList.setDataType((YangType<?>) type);
+
+                /*
+                 * If data type is derived, resolution information to be added
+                 * in resolution list.
+                 */
+                if (yangDataTypes == YangDataTypes.DERIVED) {
+                    // Parent YANG node of leaf to be added in resolution information.
+                    Parsable leafListData = listener.getParsedDataStack().pop();
+                    Parsable parentNodeOfLeafList = listener.getParsedDataStack().peek();
+                    listener.getParsedDataStack().push(leafListData);
+
+                    // Verify parent node of leaf
+                    if (!(parentNodeOfLeafList instanceof YangNode)) {
+                        throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
+                                ctx.string().getText(), EXIT));
+                    }
+
+                    // Get the prefix information
+                    String prefix = ((YangType<?>) type).getPrefix();
+
+                    // Create empty derived info and attach it to type extended info.
+                    YangDerivedInfo<?> yangDerivedInfo = new YangDerivedInfo<>();
+                    ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
+
+                    // Add resolution information to the list
+                    YangResolutionInfo resolutionInfo = new YangResolutionInfo<YangType>(type,
+                            ResolutionType.TYPEDEF_RESOLUTION, (YangNode) parentNodeOfLeafList, prefix, errorLine,
+                            errorPosition);
+                    addToResolutionList(resolutionInfo, ctx);
+                }
                 break;
             case UNION_DATA:
                 YangUnion unionNode = (YangUnion) tmpData;
@@ -130,34 +213,50 @@
                 }
                 break;
             case TYPEDEF_DATA:
-
                 /* Prepare the base type info and set in derived type */
                 YangTypeDef typeDef = (YangTypeDef) tmpData;
-                YangType<YangDerivedType> derivedType = typeDef.getDerivedType();
-                if (derivedType == null) {
-                    //TODO: set the error info correctly, to depict missing info
-                    throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
-                            ctx.string().getText(), ENTRY));
-                }
+                typeDef.setDataType((YangType<?>) type);
 
-                YangDerivedType derivedTypeInfo = new YangDerivedType();
-                if (((YangType<?>) type).getDataType() != YangDataTypes.DERIVED) {
-                    derivedTypeInfo.setEffectiveYangBuiltInType(((YangType<?>) type).getDataType());
-                } else {
-                    /*
-                     * It will be resolved in the validate data model at exit.
-                     * Nothing needs to be done.
-                     */
-                }
-                derivedTypeInfo.setBaseType((YangType<?>) type);
-                derivedType.setDataTypeExtendedInfo(derivedTypeInfo);
+                /*
+                 * If data type is derived, resolution information to be added
+                 * in resolution list.
+                 */
+                if (yangDataTypes == YangDataTypes.DERIVED) {
 
+                    // Get the prefix information
+                    String prefix = ((YangType<?>) type).getPrefix();
+
+                    // Create empty derived info and attach it to type extended info.
+                    YangDerivedInfo<?> yangDerivedInfo = new YangDerivedInfo<>();
+                    ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
+
+                    // Add resolution information to the list
+                    YangResolutionInfo resolutionInfo = new YangResolutionInfo<YangType>(type,
+                            ResolutionType.TYPEDEF_RESOLUTION, (YangNode) typeDef, prefix, errorLine, errorPosition);
+                    addToResolutionList(resolutionInfo, ctx);
+                }
                 break;
-            //TODO: union, deviate replacement statement.case TYPEDEF_DATA: //TODO
+            //TODO: deviate replacement statement.case TYPEDEF_DATA: //TODO
 
             default:
                 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
                         ctx.string().getText(), EXIT));
         }
     }
+
+    /**
+     * Add to resolution list.
+     *
+     * @param resolutionInfo resolution information.
+     * @param ctx context object of the grammar rule
+     */
+    private static void addToResolutionList(YangResolutionInfo<YangType> resolutionInfo,
+                                            GeneratedYangParser.TypeStatementContext ctx) {
+        try {
+            addResolutionInfo(resolutionInfo);
+        } catch (DataModelException e) {
+            throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
+                    TYPE_DATA, ctx.string().getText(), EXIT, e.getMessage()));
+        }
+    }
 }