[ONOS-4744] Leafref implementation and UT
Change-Id: I151797185e0bb1695c0640b667ae76ef87c4d4b0
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/ResolvableType.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/ResolvableType.java
index 058e947..80ee4a0 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/ResolvableType.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/ResolvableType.java
@@ -34,5 +34,10 @@
     /**
      * Identifies the if-feature.
      */
-    YANG_IF_FEATURE
+    YANG_IF_FEATURE,
+
+    /**
+     * Identifies the leafref.
+     */
+    YANG_LEAFREF
 }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
index da04b1a..640aa64 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
@@ -24,6 +24,11 @@
 
 import com.google.common.base.Strings;
 
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
+import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processLengthRestriction;
+import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processRangeRestriction;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypeUtils.isOfRangeRestrictedType;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BINARY;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BITS;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BOOLEAN;
@@ -34,11 +39,6 @@
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.LEAFREF;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.STRING;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UNION;
-import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
-import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
-import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypeUtils.isOfRangeRestrictedType;
-import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processLengthRestriction;
-import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processRangeRestriction;
 
 /**
  * Represents the derived information.
@@ -334,6 +334,9 @@
                     return RESOLVED;
                 }
             }
+        } else if (baseType.getDataType() == LEAFREF) {
+            setEffectiveBuiltInType(baseType.getDataType());
+            return RESOLVED;
         } else {
             setEffectiveBuiltInType(baseType.getDataType());
             /*
@@ -412,7 +415,6 @@
                 }
             }
         }
-
         /*
          * Check if the data type is the one which can't be restricted, in this
          * case check whether no self restrictions should be present.
@@ -426,7 +428,6 @@
                 throw new DataModelException("YANG file error: Restrictions can't be applied to a given type");
             }
         }
-
         // Throw exception for unsupported types
         throw new DataModelException("Linker error: Unable to process the derived type.");
     }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
new file mode 100644
index 0000000..6b49fcd
--- /dev/null
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
@@ -0,0 +1,417 @@
+/*
+ * 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.datamodel;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.datamodel.utils.Parsable;
+import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
+import org.onosproject.yangutils.datamodel.utils.YangConstructType;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
+
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
+import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
+
+/*
+ * Reference:RFC 6020.
+ * The leafref type is used to reference a particular leaf instance in
+ * the data tree.  The "path" substatement (Section 9.9.2) selects a set
+ * of leaf instances, and the leafref value space is the set of values
+ * of these leaf instances.
+ */
+
+/**
+ * Represents the leafref information.
+ *
+ * @param <T> YANG leafref info
+ */
+public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangIfFeatureHolder {
+
+    private static final long serialVersionUID = 286201644L;
+
+    /**
+     * YANG data type.
+     */
+    private YangType effectiveDataType;
+
+    /**
+     * Referred leaf/leaf-list for the path specified in the leafref type.
+     */
+    private T referredLeafOrLeafList;
+
+    /**
+     * Path of the leafref.
+     */
+    private String path;
+
+    /**
+     * Leafref path type. Either absolute or relative path.
+     */
+    private YangPathArgType pathType;
+
+    /**
+     * List of atomic paths in absolute Path.
+     */
+    private List<YangAtomicPath> atomicPath;
+
+    /**
+     * YANG relative path.
+     */
+    private YangRelativePath relativePath;
+
+    /**
+     * Status of resolution. If completely resolved enum value is "RESOLVED",
+     * if not enum value is "UNRESOLVED", in case reference of grouping/typedef/leafref
+     * is added to uses/type/leafref but it's not resolved value of enum should be
+     * "INTRA_FILE_RESOLVED".
+     */
+    private ResolvableStatus resolvableStatus;
+
+    /**
+     * Require instance status in leafref type.
+     */
+    private boolean requireInstance;
+
+    /**
+     * List of if-feature.
+     */
+    private List<YangIfFeature> ifFeatureList;
+
+    /**
+     * Returns the status of the require instance in leafref.
+     *
+     * @return status of the require instance
+     */
+    public boolean getRequireInstance() {
+        return requireInstance;
+    }
+
+    /**
+     * Sets the status of the require instance in leafref.
+     *
+     * @param requireInstance status of the require instance
+     */
+    public void setRequireInstance(boolean requireInstance) {
+        this.requireInstance = requireInstance;
+    }
+
+    /**
+     * Returns the type of data.
+     *
+     * @return the data type
+     */
+    public YangType getEffectiveDataType() {
+        return effectiveDataType;
+    }
+
+    /**
+     * Sets the type of data.
+     *
+     * @param effectiveDataType data type
+     */
+    public void setEffectiveDataType(YangType effectiveDataType) {
+        this.effectiveDataType = effectiveDataType;
+    }
+
+    /**
+     * Returns the path of the leafref.
+     *
+     * @return path of the leafref
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * Sets the path of the leafref.
+     *
+     * @param path leafref path
+     */
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    /**
+     * Returns the type of path in the leafref.
+     *
+     * @return type of path
+     */
+    public YangPathArgType getPathType() {
+        return pathType;
+    }
+
+    /**
+     * Sets the type of path in the leafref. It can be either absolute or relative type.
+     *
+     * @param pathType type of path
+     */
+    public void setPathType(YangPathArgType pathType) {
+        this.pathType = pathType;
+    }
+
+    /**
+     * Returns the list of atomic path.
+     *
+     * @return list of atomic path
+     */
+    public List<YangAtomicPath> getAtomicPath() {
+        return atomicPath;
+    }
+
+    /**
+     * Sets the list of atomic path.
+     *
+     * @param atomicPath list of atomic path.
+     */
+    public void setAtomicPath(List<YangAtomicPath> atomicPath) {
+        this.atomicPath = atomicPath;
+    }
+
+    /**
+     * Returns the object of relative path.
+     *
+     * @return object of relative path
+     */
+    public YangRelativePath getRelativePath() {
+        return relativePath;
+    }
+
+    /**
+     * Sets the object of relative path.
+     *
+     * @param relativePath object of relative path.
+     */
+    public void setRelativePath(YangRelativePath relativePath) {
+        this.relativePath = relativePath;
+    }
+
+    /**
+     * Returns the object of referred leaf/leaf-list.
+     *
+     * @return object of referred leaf/leaf-list
+     */
+    public T getReferredLeafOrLeafList() {
+        return referredLeafOrLeafList;
+    }
+
+    /**
+     * Sets the object of referred leaf/leaf-list.
+     *
+     * @param targetExtendedInfo object of referred leaf/leaf-list
+     */
+    public void setReferredLeafOrLeafList(T targetExtendedInfo) {
+        this.referredLeafOrLeafList = targetExtendedInfo;
+    }
+
+    @Override
+    public List<YangIfFeature> getIfFeatureList() {
+        return ifFeatureList;
+    }
+
+    @Override
+    public void addIfFeatureList(YangIfFeature ifFeature) {
+        if (getIfFeatureList() == null) {
+            setIfFeatureList(new LinkedList<>());
+        }
+        getIfFeatureList().add(ifFeature);
+    }
+
+    @Override
+    public void setIfFeatureList(List<YangIfFeature> ifFeatureList) {
+        this.ifFeatureList = ifFeatureList;
+    }
+
+    @Override
+    public YangConstructType getYangConstructType() {
+        return YangConstructType.LEAFREF_DATA;
+    }
+
+    @Override
+    public void validateDataOnEntry() throws DataModelException {
+        // TODO auto-generated method stub, to be implemented by parser
+    }
+
+    @Override
+    public void validateDataOnExit() throws DataModelException {
+        // TODO auto-generated method stub, to be implemented by parser
+    }
+
+    @Override
+    public ResolvableStatus getResolvableStatus() {
+        return resolvableStatus;
+    }
+
+    @Override
+    public void setResolvableStatus(ResolvableStatus resolvableStatus) {
+        this.resolvableStatus = resolvableStatus;
+    }
+
+    @Override
+    public void resolve() throws DataModelException {
+
+        if (getReferredLeafOrLeafList() == null) {
+            throw new DataModelException("Linker Error: The leafref does not refer to any leaf/leaf-list.");
+        }
+
+        // Initiate the resolution
+        try {
+            setResolvableStatus(getResolution());
+        } catch (DataModelException e) {
+            throw new DataModelException(e.getMessage());
+        }
+    }
+
+    /**
+     * Returns the resolution status by getting the effective built-in type.
+     *
+     * @return status of resolution
+     * @throws DataModelException a violation of data model rules
+     */
+    private ResolvableStatus getResolution() throws DataModelException {
+
+        if (getReferredLeafOrLeafList() instanceof YangLeaf) {
+            YangLeaf yangLeaf = ((YangLeaf) getReferredLeafOrLeafList());
+            YangType baseType = yangLeaf.getDataType();
+
+            if (baseType.getDataType() == YangDataTypes.LEAFREF) {
+                YangLeafRef referredLeafRefInfo = (YangLeafRef) (yangLeaf.getDataType().getDataTypeExtendedInfo());
+                /*
+                 * Check whether the referred typedef is resolved.
+                 */
+                if (referredLeafRefInfo.getResolvableStatus() != INTRA_FILE_RESOLVED
+                        && referredLeafRefInfo.getResolvableStatus() != RESOLVED) {
+                    throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
+                }
+
+                /*
+                 * Check if the referred typedef is intra file resolved, if yes
+                 * sets current status also to intra file resolved .
+                 */
+                if ((referredLeafRefInfo.getResolvableStatus() == INTRA_FILE_RESOLVED)) {
+                    return INTRA_FILE_RESOLVED;
+                }
+
+                // Add the if-feature list from referred leafref to current leafref.
+                List<YangIfFeature> referredLeafIfFeatureListFromLeafref = referredLeafRefInfo.getIfFeatureList();
+                if (referredLeafIfFeatureListFromLeafref != null && !referredLeafIfFeatureListFromLeafref.isEmpty()) {
+                    Iterator<YangIfFeature> referredLeafIfFeature = referredLeafIfFeatureListFromLeafref.iterator();
+                    while (referredLeafIfFeature.hasNext()) {
+                        YangIfFeature ifFeature = referredLeafIfFeature.next();
+                        addIfFeatureList(ifFeature);
+                    }
+                }
+                setEffectiveDataType(referredLeafRefInfo.getEffectiveDataType());
+            } else if (baseType.getDataType() == YangDataTypes.DERIVED) {
+                /*
+                 * Check whether the referred typedef is resolved.
+                 */
+                if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED
+                        && baseType.getResolvableStatus() != RESOLVED) {
+                    throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
+                }
+                /*
+                 * Check if the referred typedef is intra file resolved, if yes
+                 * sets current status also to intra file resolved .
+                 */
+                if ((baseType.getResolvableStatus() == INTRA_FILE_RESOLVED)) {
+                    return INTRA_FILE_RESOLVED;
+                }
+                setEffectiveDataType(baseType);
+            } else {
+                setEffectiveDataType(baseType);
+            }
+
+            // Add the if-feature list from referred leaf to current leafref.
+            List<YangIfFeature> referredLeafIfFeatureList = yangLeaf.getIfFeatureList();
+            if (referredLeafIfFeatureList != null && !referredLeafIfFeatureList.isEmpty()) {
+                Iterator<YangIfFeature> referredLeafIfFeature = referredLeafIfFeatureList.iterator();
+                while (referredLeafIfFeature.hasNext()) {
+                    YangIfFeature ifFeature = referredLeafIfFeature.next();
+                    addIfFeatureList(ifFeature);
+                }
+            }
+            return RESOLVED;
+        } else if (getReferredLeafOrLeafList() instanceof YangLeafList) {
+            YangLeafList yangLeafList = ((YangLeafList) getReferredLeafOrLeafList());
+            YangType baseType = yangLeafList.getDataType();
+
+            if (baseType.getDataType() == YangDataTypes.LEAFREF) {
+                YangLeafRef referredLeafRefInfo = (YangLeafRef) yangLeafList.getDataType().getDataTypeExtendedInfo();
+                /*
+                 * Check whether the referred typedef is resolved.
+                 */
+                if (referredLeafRefInfo.getResolvableStatus() != INTRA_FILE_RESOLVED
+                        && referredLeafRefInfo.getResolvableStatus() != RESOLVED) {
+                    throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
+                }
+                /*
+                 * Check if the referred typedef is intra file resolved, if yes
+                 * sets current status also to intra file resolved .
+                 */
+                if ((referredLeafRefInfo.getResolvableStatus() == INTRA_FILE_RESOLVED)) {
+                    return INTRA_FILE_RESOLVED;
+                }
+                // Add the if-feature list from referred leafref to current leafref.
+                List<YangIfFeature> referredLeafListIfFeatureListFromLeafref = referredLeafRefInfo.getIfFeatureList();
+                if (referredLeafListIfFeatureListFromLeafref != null
+                        && !referredLeafListIfFeatureListFromLeafref.isEmpty()) {
+                    Iterator<YangIfFeature> referredLeafListIfFeature = referredLeafListIfFeatureListFromLeafref
+                            .iterator();
+                    while (referredLeafListIfFeature.hasNext()) {
+                        YangIfFeature ifFeature = referredLeafListIfFeature.next();
+                        addIfFeatureList(ifFeature);
+                    }
+                }
+                setEffectiveDataType(referredLeafRefInfo.getEffectiveDataType());
+            } else if (baseType.getDataType() == YangDataTypes.DERIVED) {
+                /*
+                 * Check whether the referred typedef is resolved.
+                 */
+                if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED
+                        && baseType.getResolvableStatus() != RESOLVED) {
+                    throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
+                }
+                /*
+                 * Check if the referred typedef is intra file resolved, if yes
+                 * sets current status also to intra file resolved .
+                 */
+                if ((baseType.getResolvableStatus() == INTRA_FILE_RESOLVED)) {
+                    return INTRA_FILE_RESOLVED;
+                }
+                setEffectiveDataType(baseType);
+            } else {
+                setEffectiveDataType(baseType);
+            }
+            // Add the if-feature list from referred leaf-list to current leafref.
+            List<YangIfFeature> referredLeafListIfFeatureList = yangLeafList.getIfFeatureList();
+            if (referredLeafListIfFeatureList != null && !referredLeafListIfFeatureList.isEmpty()) {
+                Iterator<YangIfFeature> referredLeafListIfFeature = referredLeafListIfFeatureList.iterator();
+                while (referredLeafListIfFeature.hasNext()) {
+                    YangIfFeature ifFeature = referredLeafListIfFeature.next();
+                    addIfFeatureList(ifFeature);
+                }
+            }
+            return RESOLVED;
+        } else {
+            throw new DataModelException("Linker Error: The leafref must refer only to leaf/leaf-list.");
+        }
+    }
+}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
index 16348e5..ec25d65 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
@@ -211,6 +211,11 @@
     private List<YangResolutionInfo> ifFeatureResolutionList;
 
     /**
+     * leafref resolution list.
+     */
+    private List<YangResolutionInfo> leafrefResolutionList;
+
+    /**
      * Creates a YANG node of module type.
      */
     public YangModule() {
@@ -219,6 +224,7 @@
         derivedTypeResolutionList = new LinkedList<>();
         usesResolutionList = new LinkedList<>();
         ifFeatureResolutionList = new LinkedList<>();
+        leafrefResolutionList = new LinkedList<>();
         importList = new LinkedList<YangImport>();
         includeList = new LinkedList<YangInclude>();
         listOfLeaf = new LinkedList<YangLeaf>();
@@ -589,8 +595,10 @@
             return derivedTypeResolutionList;
         } else if (type == ResolvableType.YANG_USES) {
             return usesResolutionList;
-        } else {
+        } else if (type == ResolvableType.YANG_IF_FEATURE) {
             return ifFeatureResolutionList;
+        } else {
+            return leafrefResolutionList;
         }
     }
 
@@ -603,6 +611,8 @@
             usesResolutionList.add(resolutionInfo);
         } else if (type == ResolvableType.YANG_IF_FEATURE) {
             ifFeatureResolutionList.add(resolutionInfo);
+        } else {
+            leafrefResolutionList.add(resolutionInfo);
         }
     }
 
@@ -615,6 +625,8 @@
             usesResolutionList = resolutionList;
         } else if (type == ResolvableType.YANG_IF_FEATURE) {
             ifFeatureResolutionList.add((YangResolutionInfo) resolutionList);
+        } else if (type == ResolvableType.YANG_LEAFREF) {
+            leafrefResolutionList = resolutionList;
         }
 
     }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangSubModule.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangSubModule.java
index be7a0c0..5a5d52f 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangSubModule.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangSubModule.java
@@ -209,6 +209,11 @@
     private List<YangResolutionInfo> ifFeatureResolutionList;
 
     /**
+     * leafref resolution list.
+     */
+    private List<YangResolutionInfo> leafrefResolutionList;
+
+    /**
      * Creates a sub module node.
      */
     public YangSubModule() {
@@ -216,6 +221,7 @@
         derivedTypeResolutionList = new LinkedList<>();
         usesResolutionList = new LinkedList<>();
         ifFeatureResolutionList = new LinkedList<>();
+        leafrefResolutionList = new LinkedList<>();
         importList = new LinkedList<YangImport>();
         includeList = new LinkedList<YangInclude>();
         listOfLeaf = new LinkedList<YangLeaf>();
@@ -551,8 +557,10 @@
             return derivedTypeResolutionList;
         } else if (type == ResolvableType.YANG_USES) {
             return usesResolutionList;
-        } else {
+        } else if (type == ResolvableType.YANG_IF_FEATURE) {
             return ifFeatureResolutionList;
+        } else {
+            return leafrefResolutionList;
         }
     }
 
@@ -565,6 +573,8 @@
             usesResolutionList.add(resolutionInfo);
         } else if (type == ResolvableType.YANG_IF_FEATURE) {
             ifFeatureResolutionList.add(resolutionInfo);
+        } else {
+            leafrefResolutionList.add(resolutionInfo);
         }
     }
 
@@ -576,7 +586,9 @@
         } else if (type == ResolvableType.YANG_USES) {
             usesResolutionList = resolutionList;
         } else if (type == ResolvableType.YANG_IF_FEATURE) {
-            ifFeatureResolutionList = resolutionList;
+            ifFeatureResolutionList.add((YangResolutionInfo) resolutionList);
+        } else if (type == ResolvableType.YANG_LEAFREF) {
+            leafrefResolutionList = resolutionList;
         }
 
     }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
index 530087f..c0ac20d 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
@@ -17,6 +17,7 @@
 package org.onosproject.yangutils.datamodel;
 
 import java.io.Serializable;
+
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
 import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
@@ -43,7 +44,7 @@
  * | bit              | 9.7.4   | 0..n        | - YangBit used in YangBits         |
  * | enum             | 9.6.4   | 0..n        | - YangEnum used in YangEnumeration |
  * | length           | 9.4.4   | 0..1        | - used for string                  |
- * | path             | 9.9.2   | 0..1        | - TODO leaf-ref                    |
+ * | path             | 9.9.2   | 0..1        | - path for referred leaf/leaf-list |
  * | pattern          | 9.4.6   | 0..n        | - used for string                  |
  * | range            | 9.2.4   | 0..1        | - used for integer data type       |
  * | require-instance | 9.13.2  | 0..1        | - TODO instance-identifier         |
@@ -67,11 +68,6 @@
     private YangNodeIdentifier nodeIdentifier;
 
     /**
-     * Java package in which the Java type is defined.
-     */
-    private String javaPackage;
-
-    /**
      * YANG data type.
      */
     private YangDataTypes dataType;
@@ -137,24 +133,6 @@
     }
 
     /**
-     * Returns the Java package where the type is defined.
-     *
-     * @return Java package where the type is defined
-     */
-    public String getJavaPackage() {
-        return javaPackage;
-    }
-
-    /**
-     * Sets Java package where the type is defined.
-     *
-     * @param javaPackage Java package where the type is defined
-     */
-    public void setJavaPackage(String javaPackage) {
-        this.javaPackage = javaPackage;
-    }
-
-    /**
      * Returns the type of data.
      *
      * @return the data type
@@ -209,6 +187,16 @@
     }
 
     /**
+     * Resets the class attributes to its default value.
+     */
+    public void resetYangType() {
+        nodeIdentifier = new YangNodeIdentifier();
+        resolvableStatus = ResolvableStatus.UNRESOLVED;
+        dataType = null;
+        dataTypeExtendedInfo = null;
+    }
+
+    /**
      * Returns the type of the parsed data.
      *
      * @return returns TYPE_DATA
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index 4b8a3a1..3007ffa 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -24,6 +24,7 @@
 import org.onosproject.yangutils.datamodel.YangIfFeature;
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
 import org.onosproject.yangutils.datamodel.YangLeavesHolder;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangReferenceResolver;
@@ -171,6 +172,10 @@
                 .getEntityToResolve() instanceof YangIfFeature) {
             resolutionNode.addToResolutionList(resolutionInfo,
                     ResolvableType.YANG_IF_FEATURE);
+        } else if (resolutionInfo.getEntityToResolveInfo()
+                .getEntityToResolve() instanceof YangLeafRef) {
+            resolutionNode.addToResolutionList(resolutionInfo,
+                    ResolvableType.YANG_LEAFREF);
         }
     }
 
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/builtindatatype/YangDataTypes.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/builtindatatype/YangDataTypes.java
index 01b9028..3506c56 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/builtindatatype/YangDataTypes.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/builtindatatype/YangDataTypes.java
@@ -25,14 +25,14 @@
      *
      * int8 represents integer values between -128 and 127, inclusively.
      */
-    INT8,
+    INT8("int8"),
 
     /**
      * Reference:RFC 6020.
      *
      * int16 represents integer values between -32768 and 32767, inclusively.
      */
-    INT16,
+    INT16("int16"),
 
     /**
      * Reference:RFC 6020.
@@ -40,7 +40,7 @@
      * int32 represents integer values between -2147483648 and 2147483647,
      * inclusively.
      */
-    INT32,
+    INT32("int32"),
 
     /**
      * Reference:RFC 6020.
@@ -48,28 +48,28 @@
      * int64 represents integer values between -9223372036854775808 and
      * 9223372036854775807, inclusively.
      */
-    INT64,
+    INT64("int64"),
 
     /**
      * Reference:RFC 6020.
      *
      * uint8 represents integer values between 0 and 255, inclusively.
      */
-    UINT8,
+    UINT8("uint8"),
 
     /**
      * Reference:RFC 6020.
      *
      * uint16 represents integer values between 0 and 65535, inclusively.
      */
-    UINT16,
+    UINT16("uint16"),
 
     /**
      * Reference:RFC 6020.
      *
      * uint32 represents integer values between 0 and 4294967295, inclusively.
      */
-    UINT32,
+    UINT32("uint32"),
 
     /**
      * Reference:RFC 6020.
@@ -77,7 +77,7 @@
      * uint64 represents integer values between 0 and 18446744073709551615,
      * inclusively.
      */
-    UINT64,
+    UINT64("uint64"),
 
     /**
      * Reference:RFC 6020.
@@ -88,7 +88,7 @@
      * a negative power of ten, i.e., expressible as "i x 10^-n" where i is an
      * integer64 and n is an integer between 1 and 18, inclusively.
      */
-    DECIMAL64, // TODO: need to implement in type.
+    DECIMAL64("decimal64"), // TODO: need to implement in type.
 
     /**
      * Reference:RFC 6020.
@@ -97,14 +97,14 @@
      * characters are tab, carriage return, line feed, and the legal characters
      * of Unicode and ISO/IEC 10646
      */
-    STRING,
+    STRING("string"),
 
     /**
      * Reference:RFC 6020.
      *
      * The boolean built-in type represents a boolean value.
      */
-    BOOLEAN,
+    BOOLEAN("boolean"),
 
     /**
      * Reference:RFC 6020.
@@ -112,7 +112,7 @@
      * The enumeration built-in type represents values from a set of assigned
      * names.
      */
-    ENUMERATION,
+    ENUMERATION("enumeration"),
 
     /**
      * Reference:RFC 6020.
@@ -121,7 +121,7 @@
      * set of flags identified by small integer position numbers starting at 0.
      * Each bit number has an assigned name.
      */
-    BITS,
+    BITS("bits"),
 
     /**
      * Reference:RFC 6020.
@@ -129,7 +129,7 @@
      * The binary built-in type represents any binary data, i.e., a sequence of
      * octets.
      */
-    BINARY,
+    BINARY("binary"),
 
     /**
      * Reference:RFC 6020.
@@ -150,14 +150,14 @@
      * more features, then the leaf with the leafref type MUST also be
      * conditional based on at least the same set of features.
      */
-    LEAFREF, // TODO: need to implement in type.
+    LEAFREF("leafref"),
 
     /**
      * Reference:RFC 6020.
      *
      * The identityref type is used to reference an existing identity.
      */
-    IDENTITYREF,
+    IDENTITYREF("identityref"),
 
     /**
      * Reference:RFC 6020.
@@ -167,7 +167,7 @@
      *
      * An empty type cannot have a default value.
      */
-    EMPTY,
+    EMPTY("empty"),
 
     /**
      * Reference:RFC 6020.
@@ -189,7 +189,7 @@
      * Any default value or "units" property defined in the member types is not
      * inherited by the union type.
      */
-    UNION,
+    UNION("union"),
 
     /**
      * Reference:RFC 6020.
@@ -212,12 +212,26 @@
      * valid data. All such leaf nodes MUST reference existing nodes or leaf
      * nodes with their default value in use for the data to be valid.
      */
-    INSTANCE_IDENTIFIER,
+    INSTANCE_IDENTIFIER("instance-identifier"),
 
     /**
      * Derived data type.
      */
-    DERIVED;
+    DERIVED("derived");
+
+    /**
+     * Defined type from the enum value.
+     */
+    private String definedType;
+
+    /**
+     * Constructs type value from enum.
+     *
+     * @param definedType value of enum
+     */
+    YangDataTypes(String definedType) {
+        this.definedType = definedType;
+    }
 
     /**
      * Returns YANG data type for corresponding type name.
@@ -228,7 +242,7 @@
     public static YangDataTypes getType(String name) {
         name = name.replace("\"", "");
         for (YangDataTypes yangDataType : values()) {
-            if (yangDataType.name().toLowerCase().equals(name)) {
+            if (yangDataType.definedType.toLowerCase().equals(name)) {
                 return yangDataType;
             }
         }