[ONOS-4350] Inter file linking implementation and inter-jar linking framework
Change-Id: I71a26ba3e0b9d17261e78a9313fe7f047195932e
diff --git a/src/main/java/org/onosproject/yangutils/linker/YangLinker.java b/src/main/java/org/onosproject/yangutils/linker/YangLinker.java
index f659fa9..bbb673a 100644
--- a/src/main/java/org/onosproject/yangutils/linker/YangLinker.java
+++ b/src/main/java/org/onosproject/yangutils/linker/YangLinker.java
@@ -16,8 +16,8 @@
package org.onosproject.yangutils.linker;
-import java.util.Map;
-import org.onosproject.yangutils.datamodel.YangReferenceResolver;
+import java.util.Set;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
/**
* Abstraction of entity which provides linking service of YANG files.
@@ -28,8 +28,7 @@
* Resolve the import and include dependencies for a given resolution
* information.
*
- * @param fileMapEntry map entry for which resolution is to be done
- * @param yangFilesMap map of dependent file and resolution information*/
- void resolveDependencies(Map.Entry<String, YangReferenceResolver> fileMapEntry, Map<String,
- YangReferenceResolver> yangFilesMap);
+ * @param yangFileInfoSet set of all dependent YANG files
+ */
+ void resolveDependencies(Set<YangFileInfo> yangFileInfoSet);
}
diff --git a/src/main/java/org/onosproject/yangutils/linker/exceptions/LinkerException.java b/src/main/java/org/onosproject/yangutils/linker/exceptions/LinkerException.java
new file mode 100644
index 0000000..755b5b4
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/linker/exceptions/LinkerException.java
@@ -0,0 +1,117 @@
+/*
+ * 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.linker.exceptions;
+
+/**
+ * Represents base class for exceptions in linker operations.
+ */
+public class LinkerException extends RuntimeException {
+
+ private static final long serialVersionUID = 20160211L;
+ private int lineNumber;
+ private int charPositionInLine;
+ private String fileName;
+
+ /**
+ * Creates a new linker exception.
+ */
+ public LinkerException() {
+ super();
+ }
+
+ /**
+ * Creates a new linker exception with given message.
+ *
+ * @param message the detail of exception in string
+ */
+ public LinkerException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new linker exception from given message and cause.
+ *
+ * @param message the detail of exception in string
+ * @param cause underlying cause of the error
+ */
+ public LinkerException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Creates a new linker exception from cause.
+ *
+ * @param cause underlying cause of the error
+ */
+ public LinkerException(final Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Returns line number of the exception.
+ *
+ * @return line number of the exception
+ */
+ public int getLineNumber() {
+ return this.lineNumber;
+ }
+
+ /**
+ * Returns YANG file name of the exception.
+ *
+ * @return YANG file name of the exception
+ */
+ public String getFileName() {
+ return this.fileName;
+ }
+
+ /**
+ * Returns position of the exception.
+ *
+ * @return position of the exception
+ */
+ public int getCharPositionInLine() {
+ return this.charPositionInLine;
+ }
+
+ /**
+ * Sets line number of YANG file.
+ *
+ * @param line line number of YANG file
+ */
+ public void setLine(int line) {
+ this.lineNumber = line;
+ }
+
+ /**
+ * Sets position of exception.
+ *
+ * @param charPosition position of exception
+ */
+ public void setCharPosition(int charPosition) {
+ this.charPositionInLine = charPosition;
+ }
+
+ /**
+ * Sets file name in parser exception.
+ *
+ * @param fileName YANG file name
+ */
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+}
diff --git a/src/main/java/org/onosproject/yangutils/linker/exceptions/package-info.java b/src/main/java/org/onosproject/yangutils/linker/exceptions/package-info.java
new file mode 100644
index 0000000..42cf3a2
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/linker/exceptions/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.
+ */
+
+/**
+ * Custom linker exceptions.
+ */
+package org.onosproject.yangutils.linker.exceptions;
diff --git a/src/main/java/org/onosproject/yangutils/linker/impl/Resolvable.java b/src/main/java/org/onosproject/yangutils/linker/impl/Resolvable.java
new file mode 100644
index 0000000..f384dc5
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/linker/impl/Resolvable.java
@@ -0,0 +1,54 @@
+/*
+ * 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.linker.impl;
+
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+
+/**
+ * Abstraction of YANG resolvable information. Abstracted to obtain the
+ * information required for linking resolution.
+ */
+public interface Resolvable {
+
+ /**
+ * Returns the status of resolution. If completely resolved returns enum
+ * value "RESOLVED", if not returns "UNRESOLVED", in case reference of
+ * grouping/typedef is added to uses/type but it's not resolved
+ * "INTRA_FILE_RESOLVED" is returned.
+ *
+ * @return status of resolution
+ */
+ ResolvableStatus getResolvableStatus();
+
+ /**
+ * Set the status of type/uses resolution. If completely resolved set enum
+ * value "RESOLVED", if not set it to "UNRESOLVED", in case reference of
+ * grouping/typedef is added to uses/type but it's not resolved
+ * "INTRA_FILE_RESOLVED" should be set.
+ *
+ * @param resolvableStatus status of resolution
+ */
+ void setResolvableStatus(ResolvableStatus resolvableStatus);
+
+ /**
+ * Resolves the linking.
+ *
+ * @throws LinkerException linker error
+ */
+ void resolve()
+ throws LinkerException;
+}
diff --git a/src/main/java/org/onosproject/yangutils/linker/impl/ResolvableStatus.java b/src/main/java/org/onosproject/yangutils/linker/impl/ResolvableStatus.java
new file mode 100644
index 0000000..cd43c18
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/linker/impl/ResolvableStatus.java
@@ -0,0 +1,51 @@
+/*
+ * 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.linker.impl;
+
+/**
+ * Represents the status of resolvable entity.
+ */
+public enum ResolvableStatus {
+
+ /**
+ * Identifies that resolvable entity is unresolved.
+ */
+ UNRESOLVED,
+
+ /**
+ * Identifies that resolvable entity's reference is linked.
+ */
+ LINKED,
+
+ /**
+ * Identifies that resolvable entity is IntraFile resolved (i.e. complete
+ * linking with in the intra file).
+ */
+ INTRA_FILE_RESOLVED,
+
+ /**
+ * Identifies that resolvable entity is resolved.
+ */
+ RESOLVED,
+
+ /**
+ * Identifies that resolvable entity is inter file linked (i.e. complete
+ * linking with external files).
+ */
+ INTER_FILE_LINKED
+
+}
diff --git a/src/main/java/org/onosproject/yangutils/linker/impl/YangEntityToResolveInfo.java b/src/main/java/org/onosproject/yangutils/linker/impl/YangEntityToResolveInfo.java
new file mode 100644
index 0000000..f239692
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/linker/impl/YangEntityToResolveInfo.java
@@ -0,0 +1,96 @@
+/*
+ * 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.linker.impl;
+
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.YangUses;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+
+/**
+ * Represents information about entity being resolved.
+ *
+ * @param <T> type of entity being resolved, uses / grouping
+ */
+public class YangEntityToResolveInfo<T> {
+
+ // Parsable node for which resolution is to be performed.
+ private T entityToResolve;
+
+ // Holder of the YANG construct for which resolution has to be carried out.
+ private YangNode holderOfEntityToResolve;
+
+ /**
+ * Retrieves the entity to be resolved.
+ *
+ * @return entity to be resolved
+ */
+ public T getEntityToResolve() {
+ return entityToResolve;
+ }
+
+ /**
+ * Sets entity to be resolved.
+ *
+ * @param entityToResolve entity to be resolved
+ */
+ public void setEntityToResolve(T entityToResolve) {
+ this.entityToResolve = entityToResolve;
+ }
+
+ /**
+ * Retrieves the parent node which contains the entity to be resolved.
+ *
+ * @return parent node which contains the entity to be resolved
+ */
+ public YangNode getHolderOfEntityToResolve() {
+ return holderOfEntityToResolve;
+ }
+
+ /**
+ * Sets parent node which contains the entity to be resolved.
+ *
+ * @param holderOfEntityToResolve parent node which contains the entity to
+ * be resolved
+ */
+ public void setHolderOfEntityToResolve(YangNode holderOfEntityToResolve) {
+ this.holderOfEntityToResolve = holderOfEntityToResolve;
+ }
+
+ /**
+ * Retrieves the prefix of the entity.
+ *
+ * @return entities prefix
+ * @throws LinkerException linker error
+ */
+ public String getEntityPrefix()
+ throws LinkerException {
+ if (getEntityToResolve() == null) {
+ return null;
+ }
+
+ String prefix;
+ T entityToBeResolved = getEntityToResolve();
+ if (entityToBeResolved instanceof YangType) {
+ prefix = ((YangType<?>) entityToBeResolved).getPrefix();
+ } else if (entityToBeResolved instanceof YangUses) {
+ prefix = ((YangUses) entityToBeResolved).getPrefix();
+ } else {
+ throw new LinkerException("Linker Exception: Entity to resolved is other than type/uses");
+ }
+ return prefix;
+ }
+}
diff --git a/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java b/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
new file mode 100644
index 0000000..0fc3d99
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerManager.java
@@ -0,0 +1,120 @@
+/*
+ * 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.linker.impl;
+
+import java.util.Set;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.linker.YangLinker;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
+
+import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
+
+/**
+ * Representation of entity which provides linking service of YANG files.
+ */
+public class YangLinkerManager implements YangLinker {
+ @Override
+ public void resolveDependencies(Set<YangFileInfo> yangFileInfoSet) {
+
+ // Carry out linking of sub module with module.
+ linkSubModulesToParentModule(yangFileInfoSet);
+
+ // Add references to import list.
+ addRefToYangFilesImportList(yangFileInfoSet);
+
+ // Add reference to include list.
+ addRefToYangFilesIncludeList(yangFileInfoSet);
+
+ // TODO check for circular import/include.
+
+ // Carry out inter-file linking.
+ processInterFileLinking(yangFileInfoSet);
+ }
+
+ /**
+ * Resolves sub-module linking by linking sub module with parent module.
+ *
+ * @param yangFileInfoSet set of YANG files info
+ * @throws LinkerException fails to link sub-module to parent module
+ */
+ public void linkSubModulesToParentModule(Set<YangFileInfo> yangFileInfoSet) throws LinkerException {
+ for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+ YangNode yangNode = yangFileInfo.getRootNode();
+ if (yangNode instanceof YangSubModule) {
+ try {
+ ((YangSubModule) yangNode).linkWithModule(yangFileInfoSet);
+ } catch (DataModelException e) {
+ String errorInfo = "YANG file error: " + yangFileInfo.getYangFileName() + " at line: "
+ + e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE
+ + e.getMessage();
+ throw new LinkerException(errorInfo);
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds imported node information to the import list.
+ *
+ * @param yangFileInfoSet set of YANG files info
+ * @throws LinkerException fails to find imported module
+ */
+ public void addRefToYangFilesImportList(Set<YangFileInfo> yangFileInfoSet) throws LinkerException {
+ for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+ YangNode yangNode = yangFileInfo.getRootNode();
+ if (yangNode instanceof YangReferenceResolver) {
+ ((YangReferenceResolver) yangNode).addReferencesToImportList(yangFileInfoSet);
+ }
+ }
+ }
+
+ /**
+ * Adds included node information to the include list.
+ *
+ * @param yangFileInfoSet set of YANG files info
+ * @throws LinkerException fails to find included sub-module
+ */
+ public void addRefToYangFilesIncludeList(Set<YangFileInfo> yangFileInfoSet) throws LinkerException {
+ for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+ YangNode yangNode = yangFileInfo.getRootNode();
+ if (yangNode instanceof YangReferenceResolver) {
+ ((YangReferenceResolver) yangNode).addReferencesToIncludeList(yangFileInfoSet);
+ }
+ }
+ }
+
+ /**
+ * Processes inter file linking for type and uses.
+ *
+ * @param yangFileInfoSet set of YANG files info
+ * @throws LinkerException a violation in linker execution
+ */
+ public void processInterFileLinking(Set<YangFileInfo> yangFileInfoSet) throws LinkerException {
+ for (YangFileInfo yangFileInfo : yangFileInfoSet) {
+ try {
+ ((YangReferenceResolver) yangFileInfo.getRootNode()).resolveInterFileLinking();
+ } catch (DataModelException e) {
+ String errorInfo = "Error in file: " + yangFileInfo.getYangFileName() + " at line: "
+ + e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE + e.getMessage();
+ throw new LinkerException(errorInfo);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/onosproject/yangutils/linker/impl/YangReferenceResolver.java b/src/main/java/org/onosproject/yangutils/linker/impl/YangReferenceResolver.java
new file mode 100644
index 0000000..4681985
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/linker/impl/YangReferenceResolver.java
@@ -0,0 +1,139 @@
+/*
+ * 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.linker.impl;
+
+import java.util.List;
+import java.util.Set;
+import org.onosproject.yangutils.datamodel.YangImport;
+import org.onosproject.yangutils.datamodel.YangInclude;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.plugin.manager.YangFileInfo;
+
+/**
+ * Abstraction of YANG dependency resolution information. Abstracted to obtain the
+ * resolution information.
+ */
+public interface YangReferenceResolver {
+
+ /**
+ * Returns unresolved resolution list.
+ *
+ * @return unresolved resolution list
+ */
+ List<YangResolutionInfo> getUnresolvedResolutionList();
+
+ /**
+ * Adds to the resolution list.
+ *
+ * @param resolutionInfo resolution information
+ */
+ void addToResolutionList(YangResolutionInfo resolutionInfo);
+
+ /**
+ * Creates resolution list.
+ *
+ * @param resolutionList resolution list
+ */
+ void setResolutionList(List<YangResolutionInfo> resolutionList);
+
+ /**
+ * Returns unresolved imported list.
+ *
+ * @return unresolved imported list
+ */
+ List<YangImport> getImportList();
+
+ /**
+ * Adds to the import list.
+ *
+ * @param yangImport import to be added
+ */
+ void addToImportList(YangImport yangImport);
+
+ /**
+ * Create import list.
+ *
+ * @param importList import list
+ */
+ void setImportList(List<YangImport> importList);
+
+ /**
+ * Returns unresolved include list.
+ *
+ * @return unresolved include list
+ */
+ List<YangInclude> getIncludeList();
+
+ /**
+ * Adds to the include list.
+ *
+ * @param yangInclude include to be added
+ */
+ void addToIncludeList(YangInclude yangInclude);
+
+ /**
+ * Creates include list.
+ *
+ * @param includeList include list
+ */
+ void setIncludeList(List<YangInclude> includeList);
+
+ /**
+ * Returns prefix of resolution root node.
+ *
+ * @return prefix resolution root node prefix
+ */
+ String getPrefix();
+
+ /**
+ * Sets prefix of resolution list root node.
+ *
+ * @param prefix resolution root node prefix
+ */
+ void setPrefix(String prefix);
+
+ /**
+ * Resolves self file linking.
+ *
+ * @throws DataModelException a violation in data model rule
+ */
+ void resolveSelfFileLinking() throws DataModelException;
+
+ /**
+ * Resolves inter file linking.
+ *
+ * @throws DataModelException a violation in data model rule
+ */
+ void resolveInterFileLinking() throws DataModelException;
+
+ /**
+ * Adds references to include.
+ *
+ * @param yangFileInfoSet YANG file info set
+ * @throws LinkerException a violation of linker rules
+ */
+ void addReferencesToIncludeList(Set<YangFileInfo> yangFileInfoSet) throws LinkerException;
+
+ /**
+ * Adds references to import.
+ *
+ * @param yangFileInfoSet YANG file info set
+ * @throws LinkerException a violation of linker rules
+ */
+ void addReferencesToImportList(Set<YangFileInfo> yangFileInfoSet) throws LinkerException;
+}
diff --git a/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfo.java b/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfo.java
new file mode 100644
index 0000000..d838440
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfo.java
@@ -0,0 +1,855 @@
+/*
+ * 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.linker.impl;
+
+import java.util.Stack;
+import org.onosproject.yangutils.datamodel.LocationInfo;
+import org.onosproject.yangutils.datamodel.YangDataTypes;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangGrouping;
+import org.onosproject.yangutils.datamodel.YangImport;
+import org.onosproject.yangutils.datamodel.YangInclude;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.YangTypeDef;
+import org.onosproject.yangutils.datamodel.YangUses;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+
+import static org.onosproject.yangutils.linker.impl.ResolvableStatus.INTER_FILE_LINKED;
+import static org.onosproject.yangutils.linker.impl.ResolvableStatus.INTRA_FILE_RESOLVED;
+import static org.onosproject.yangutils.linker.impl.ResolvableStatus.LINKED;
+import static org.onosproject.yangutils.linker.impl.ResolvableStatus.RESOLVED;
+import static org.onosproject.yangutils.linker.impl.ResolvableStatus.UNRESOLVED;
+
+/**
+ * Represents resolution object which will be resolved by linker.
+ *
+ * @param <T> type of resolution entity uses / type
+ */
+public class YangResolutionInfo<T> implements LocationInfo {
+
+ /**
+ * Information about the entity that needs to be resolved.
+ */
+ private YangEntityToResolveInfo<T> entityToResolveInfo;
+
+ /**
+ * Error line number.
+ */
+ private int lineNumber;
+
+ /**
+ * Error character position in number.
+ */
+ private int charPosition;
+
+ /**
+ * Current module/sub-module reference, will be used in inter-file/
+ * inter-jar scenario to get the import/include list.
+ */
+ private YangReferenceResolver curReferenceResolver;
+
+ /**
+ * Stack for type/uses is maintained for hierarchical references, this is
+ * used during resolution.
+ */
+ private Stack<YangEntityToResolveInfo<T>> partialResolvedStack;
+
+ /**
+ * It is private to ensure the overloaded method be invoked to create an
+ * object.
+ */
+ @SuppressWarnings("unused")
+ private YangResolutionInfo() {
+
+ }
+
+ /**
+ * Creates a resolution information object with all the inputs.
+ *
+ * @param dataNode current parsable data node
+ * @param holderNode parent YANG node
+ * @param lineNumber error line number
+ * @param charPositionInLine error character position in line
+ */
+ public YangResolutionInfo(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
+ setEntityToResolveInfo(new YangEntityToResolveInfo<>());
+ getEntityToResolveInfo().setEntityToResolve(dataNode);
+ getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
+ this.setLineNumber(lineNumber);
+ this.setCharPosition(charPositionInLine);
+ setPartialResolvedStack(new Stack<>());
+ }
+
+ /**
+ * Resolves linking with all the ancestors node for a resolution info.
+ *
+ * @param dataModelRootNode module/sub-module node
+ * @throws DataModelException DataModelException a violation of data model
+ * rules
+ */
+ public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
+ throws DataModelException {
+
+ setCurReferenceResolver(dataModelRootNode);
+
+ // Current node to resolve, it can be a YANG type or YANG uses.
+ T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
+
+ // Check if linking is already done
+ if (entityToResolve instanceof Resolvable) {
+ Resolvable resolvable = (Resolvable) entityToResolve;
+ if (resolvable.getResolvableStatus() == RESOLVED) {
+ /**
+ * entity is already resolved, so nothing to do
+ */
+ return;
+ }
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+
+ // Push the initial entity to resolve in stack.
+ addInPartialResolvedStack(getEntityToResolveInfo());
+
+ linkAndResolvePartialResolvedStack();
+ }
+
+ /**
+ * Resolves linking with ancestors.
+ *
+ * @throws DataModelException a violation of data model rules
+ */
+ private void linkAndResolvePartialResolvedStack()
+ throws DataModelException {
+
+ while (getPartialResolvedStack().size() != 0) {
+
+ // Current node to resolve, it can be a YANG type or YANG uses.
+ T entityToResolve = getCurrentEntityToResolveFromStack();
+ // Check if linking is already done
+ if (entityToResolve instanceof Resolvable) {
+
+ Resolvable resolvable = (Resolvable) entityToResolve;
+ switch (resolvable.getResolvableStatus()) {
+ case RESOLVED: {
+ /*
+ * If the entity is already resolved in the stack, then
+ * pop it and continue with the remaining stack elements
+ * to resolve
+ */
+ getPartialResolvedStack().pop();
+ break;
+ }
+
+ case LINKED: {
+ /*
+ * If the top of the stack is already linked then
+ * resolve the references and pop the entity and
+ * continue with remaining stack elements to resolve.
+ */
+ resolveTopOfStack();
+ getPartialResolvedStack().pop();
+ break;
+ }
+
+ case INTRA_FILE_RESOLVED: {
+ /*
+ * Pop the top of the stack.
+ */
+ getPartialResolvedStack().pop();
+ break;
+ }
+
+ case UNRESOLVED: {
+ linkTopOfStackReferenceUpdateStack();
+
+ if (resolvable.getResolvableStatus() == UNRESOLVED) {
+ // If current entity is still not resolved, then linking/resolution has failed.
+ DataModelException dataModelException =
+ new DataModelException("YANG file error: Unable to find base "
+ + "typedef/grouping for given type/uses");
+ dataModelException.setLine(getLineNumber());
+ dataModelException.setCharPosition(getCharPosition());
+ throw dataModelException;
+ }
+ break;
+ }
+ default: {
+ throw new DataModelException("Data Model Exception: Unsupported, linker state");
+ }
+
+ }
+
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+
+ }
+
+ }
+
+ /**
+ * Resolves the current entity in the stack.
+ */
+ private void resolveTopOfStack()
+ throws DataModelException {
+ ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
+ if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus()
+ != INTRA_FILE_RESOLVED) {
+ // Sets the resolution status in inside the type/uses.
+ ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
+ }
+ }
+
+ /**
+ * Resolves linking for a node child and siblings.
+ *
+ * @throws DataModelException data model error
+ */
+ private void linkTopOfStackReferenceUpdateStack()
+ throws DataModelException {
+
+ /*
+ * Check if self file reference is there, this will not check for the
+ * scenario when prefix is not present and type/uses is present in
+ * sub-module from include list.
+ */
+ if (!isCandidateForSelfFileReference()) {
+ ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
+ return;
+ }
+
+ /**
+ * Try to resolve the top of the stack and update partial resolved stack
+ * if there is recursive references
+ */
+ YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
+ .getHolderOfEntityToResolve();
+
+ /**
+ * Traverse up in the ancestor tree to check if the referred node is
+ * defined
+ */
+ while (potentialAncestorWithReferredNode != null) {
+
+ /**
+ * Check for the referred node defined in a ancestor scope
+ */
+ YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
+ if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
+ return;
+ }
+
+ potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
+ }
+
+ /*
+ * In case prefix is not present it's a candidate for inter-file
+ * resolution via include list.
+ */
+ if (getRefPrefix() == null) {
+ ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
+ }
+ }
+
+ /**
+ * Checks if the reference in self file or in external file.
+ *
+ * @return true if self file reference, false otherwise
+ * @throws DataModelException a violation of data model rules
+ */
+ private boolean isCandidateForSelfFileReference() throws DataModelException {
+ String prefix = getRefPrefix();
+ return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
+ }
+
+ /**
+ * Checks for the referred node defined in a ancestor scope.
+ *
+ * @param potentialReferredNode potential referred node
+ * @return status of resolution and updating the partial resolved stack with
+ * the any recursive references
+ * @throws DataModelException data model errors
+ */
+ private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
+ throws DataModelException {
+ while (potentialReferredNode != null) {
+
+ // Check if the potential referred node is the actual referred node
+ if (isReferredNode(potentialReferredNode)) {
+
+ // Adds reference link of entity to the node under resolution.
+ addReferredEntityLink(potentialReferredNode, LINKED);
+
+ /**
+ * resolve the reference and update the partial resolution stack
+ * with any further recursive references
+ */
+ addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
+
+ /*
+ * return true, since the reference is linked and any recursive
+ * unresolved references is added to the stack
+ */
+ return true;
+ }
+
+ potentialReferredNode = potentialReferredNode.getNextSibling();
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the potential referred node is the actual referred node.
+ *
+ * @param potentialReferredNode typedef/grouping node
+ * @return true if node is of resolve type otherwise false
+ * @throws DataModelException a violation of data model rules
+ */
+ private boolean isReferredNode(YangNode potentialReferredNode)
+ throws DataModelException {
+ if (getCurrentEntityToResolveFromStack() instanceof YangType) {
+ if (potentialReferredNode instanceof YangTypeDef) {
+ /*
+ * Check if name of node name matches with the entity being
+ * resolved
+ */
+ return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
+ }
+ } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
+ if (potentialReferredNode instanceof YangGrouping) {
+ /*
+ * Check if name of node name matches with the entity being
+ * resolved
+ */
+ return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
+ }
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+ return false;
+ }
+
+ /**
+ * Checks if node name is same as name in resolution info, i.e. name of
+ * typedef/grouping is same as name of type/uses.
+ *
+ * @param node typedef/grouping node
+ * @return true if node name is same as name in resolution info, otherwise
+ * false
+ * @throws DataModelException a violation of data model rules
+ */
+
+ private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
+ throws DataModelException {
+ if (getCurrentEntityToResolveFromStack() instanceof YangType) {
+ if (node.getName().contentEquals(
+ ((YangType<?>) getCurrentEntityToResolveFromStack())
+ .getDataTypeName())) {
+ return true;
+ }
+ } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
+ if (node.getName().contentEquals(
+ ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
+ return true;
+ }
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+ return false;
+ }
+
+ /**
+ * Adds reference of grouping/typedef in uses/type.
+ *
+ * @param referredNode grouping/typedef node being referred
+ * @param linkedStatus linked status if success.
+ * @throws DataModelException a violation of data model rules
+ */
+ private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
+ throws DataModelException {
+ if (getCurrentEntityToResolveFromStack() instanceof YangType) {
+ YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>)
+ ((YangType<?>) getCurrentEntityToResolveFromStack()).getDataTypeExtendedInfo();
+ derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
+ } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
+ ((YangUses) getCurrentEntityToResolveFromStack())
+ .setRefGroup((YangGrouping) referredNode);
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+
+ // Sets the resolution status in inside the type/uses.
+ ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
+ }
+
+ /**
+ * Checks if type/grouping has further reference to typedef/ unresolved
+ * uses. Add it to the partial resolve stack and return the status of
+ * addition to stack.
+ *
+ * @param referredNode grouping/typedef node
+ * @throws DataModelException a violation of data model rules
+ */
+ private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
+ throws DataModelException {
+ if (getCurrentEntityToResolveFromStack() instanceof YangType) {
+ /*
+ * Checks if typedef type is derived
+ */
+ if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType()
+ == YangDataTypes.DERIVED) {
+
+ YangEntityToResolveInfo<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfo<>();
+ unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
+ .getTypeDefBaseType());
+ unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
+ addInPartialResolvedStack((YangEntityToResolveInfo<T>) unResolvedEntityInfo);
+ }
+
+ } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
+ /*
+ * Search if the grouping has any un resolved uses child, if so
+ * return true, else return false.
+ */
+ addUnResolvedUsesToStack(referredNode);
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+ }
+
+ /**
+ * Returns if there is any unresolved uses in grouping.
+ *
+ * @param node grouping/typedef node
+ */
+ private void addUnResolvedUsesToStack(YangNode node) {
+
+ /**
+ * Search the grouping node's children for presence of uses node.
+ */
+ YangNode curNode = node.getChild();
+ while (curNode != null) {
+ if (curNode instanceof YangUses) {
+ YangEntityToResolveInfo<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfo<>();
+ unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
+ unResolvedEntityInfo.setHolderOfEntityToResolve(node);
+ addInPartialResolvedStack((YangEntityToResolveInfo<T>) unResolvedEntityInfo);
+
+ }
+ curNode = curNode.getNextSibling();
+ }
+ }
+
+ /**
+ * Returns stack of YANG type with partially resolved YANG construct
+ * hierarchy.
+ *
+ * @return partial resolved YANG construct stack
+ */
+ private Stack<YangEntityToResolveInfo<T>> getPartialResolvedStack() {
+ return partialResolvedStack;
+ }
+
+ /**
+ * Sets stack of YANG type with partially resolved YANG construct hierarchy.
+ *
+ * @param partialResolvedStack partial resolved YANG construct stack
+ */
+ private void setPartialResolvedStack(Stack<YangEntityToResolveInfo<T>> partialResolvedStack) {
+ this.partialResolvedStack = partialResolvedStack;
+ }
+
+ /**
+ * Sets stack of YANG type with partially resolved YANG construct hierarchy.
+ *
+ * @param partialResolvedInfo partial resolved YANG construct stack
+ */
+ private void addInPartialResolvedStack(YangEntityToResolveInfo<T> partialResolvedInfo) {
+ getPartialResolvedStack().push(partialResolvedInfo);
+ }
+
+ /**
+ * Retrieves the next entity in the stack that needs to be resolved. It is
+ * assumed that the caller ensures that the stack is not empty.
+ *
+ * @return next entity in the stack that needs to be resolved
+ */
+ private T getCurrentEntityToResolveFromStack() {
+ return getPartialResolvedStack().peek().getEntityToResolve();
+ }
+
+ /**
+ * Retrieves information about the entity that needs to be resolved.
+ *
+ * @return information about the entity that needs to be resolved
+ */
+ public YangEntityToResolveInfo<T> getEntityToResolveInfo() {
+ return entityToResolveInfo;
+ }
+
+ /**
+ * Sets information about the entity that needs to be resolved.
+ *
+ * @param entityToResolveInfo information about the entity that needs to be
+ * resolved
+ */
+ private void setEntityToResolveInfo(YangEntityToResolveInfo<T> entityToResolveInfo) {
+ this.entityToResolveInfo = entityToResolveInfo;
+ }
+
+ @Override
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ @Override
+ public int getCharPosition() {
+ return charPosition;
+ }
+
+ @Override
+ public void setLineNumber(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ @Override
+ public void setCharPosition(int charPositionInLine) {
+ this.charPosition = charPositionInLine;
+ }
+
+ /**
+ * Returns current module/sub-module reference, will be used in inter-file/
+ * inter-jar scenario to get the import/include list.
+ *
+ * @return current module/sub-module reference
+ */
+ private YangReferenceResolver getCurReferenceResolver() {
+ return curReferenceResolver;
+ }
+
+ /**
+ * Sets current module/sub-module reference, will be used in inter-file/
+ * inter-jar scenario to get the import/include list.
+ *
+ * @param curReferenceResolver current module/sub-module reference
+ */
+ private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
+ this.curReferenceResolver = curReferenceResolver;
+ }
+
+ /**
+ * Performs inter file linking of uses/type referring to typedef/grouping
+ * of other YANG file.
+ *
+ * @param dataModelRootNode module/sub-module node
+ * @throws DataModelException a violation in data model rule
+ */
+ public void linkInterFile(YangReferenceResolver dataModelRootNode)
+ throws DataModelException {
+
+ setCurReferenceResolver(dataModelRootNode);
+
+ // Current node to resolve, it can be a YANG type or YANG uses.
+ T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
+
+ // Check if linking is already done
+ if (entityToResolve instanceof Resolvable) {
+ Resolvable resolvable = (Resolvable) entityToResolve;
+ if (resolvable.getResolvableStatus() == RESOLVED) {
+ return;
+ }
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
+ }
+
+ // Push the initial entity to resolve in stack.
+ addInPartialResolvedStack(getEntityToResolveInfo());
+
+ // Inter file linking and resolution.
+ linkInterFileAndResolve();
+ }
+
+ /**
+ * Returns the referenced prefix of entity under resolution.
+ *
+ * @return referenced prefix of entity under resolution
+ * @throws DataModelException a violation in data model rule
+ */
+ private String getRefPrefix() throws DataModelException {
+ String refPrefix;
+ if (getCurrentEntityToResolveFromStack() instanceof YangType) {
+ refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
+ } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
+ refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+ return refPrefix;
+ }
+
+ /**
+ * Performs inter file linking and resolution.
+ *
+ * @throws DataModelException a violation in data model rule
+ */
+ private void linkInterFileAndResolve()
+ throws DataModelException {
+
+ while (getPartialResolvedStack().size() != 0) {
+
+ // Current node to resolve, it can be a YANG type or YANG uses.
+ T entityToResolve = getCurrentEntityToResolveFromStack();
+ // Check if linking is already done
+ if (entityToResolve instanceof Resolvable) {
+
+ Resolvable resolvable = (Resolvable) entityToResolve;
+ switch (resolvable.getResolvableStatus()) {
+ case RESOLVED: {
+ /*
+ * If the entity is already resolved in the stack, then
+ * pop it and continue with the remaining stack elements
+ * to resolve
+ */
+ getPartialResolvedStack().pop();
+ break;
+ }
+
+ case INTER_FILE_LINKED: {
+ /*
+ * If the top of the stack is already linked then
+ * resolve the references and pop the entity and
+ * continue with remaining stack elements to resolve
+ */
+ resolveTopOfStack();
+ getPartialResolvedStack().pop();
+ break;
+ }
+
+ case INTRA_FILE_RESOLVED: {
+ /*
+ * If the top of the stack is intra file resolved
+ * then check if top of stack is linked, if not
+ * link it using import/include list and push the
+ * linked referred entity to the stack, otherwise
+ * only push it to the stack.
+ */
+ linkInterFileTopOfStackRefUpdateStack();
+ break;
+ }
+
+ default: {
+ throw new DataModelException("Data Model Exception: Unsupported, linker state");
+ }
+
+ }
+
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+
+ }
+
+ }
+
+ /**
+ * Links the top of the stack if it's inter-file and update stack.
+ *
+ * @throws DataModelException data model error
+ */
+ private void linkInterFileTopOfStackRefUpdateStack() throws DataModelException {
+
+ /*
+ * Obtain the referred node of top of stack entity under resolution
+ */
+ T referredNode = getRefNode();
+
+ /*
+ * Check for null for scenario when it's not linked and inter-file
+ * linking is required.
+ */
+ if (referredNode == null) {
+
+ /*
+ * Check if prefix is null or not, to identify whether to search
+ * in import list or include list.
+ */
+ if (getRefPrefix() != null && !(getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix()))) {
+ if (resolveWithImport()) {
+ return;
+ }
+ } else {
+ if (resolveWithInclude()) {
+ return;
+ }
+ }
+ // Exception when referred typedef/grouping is not found.
+ DataModelException dataModelException = new DataModelException("YANG file error: Referred " +
+ "typedef/grouping for a given type/uses can't be found.");
+ dataModelException.setLine(getLineNumber());
+ dataModelException.setCharPosition(getCharPosition());
+ throw dataModelException;
+ } else {
+ /*
+ * If referred node is already linked, then just change the status
+ * and push to the stack.
+ */
+ ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
+ addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
+ }
+ }
+
+ /**
+ * Finds and resolves with include list.
+ *
+ * @return true if resolved, false otherwise
+ * @throws DataModelException a violation in data model rule
+ */
+ private boolean resolveWithInclude() throws DataModelException {
+ /*
+ * Run through all the nodes in include list and search for referred
+ * typedef/grouping at the root level.
+ */
+ for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
+ YangNode linkedNode = null;
+ if (getCurrentEntityToResolveFromStack() instanceof YangType) {
+ linkedNode = findRefTypedef(yangInclude.getIncludedNode());
+ } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
+ linkedNode = findRefGrouping(yangInclude.getIncludedNode());
+ }
+ if (linkedNode != null) {
+ // Add the link to external entity.
+ addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
+ /*
+ * Update the current reference resolver to external
+ * module/sub-module containing the referred typedef/grouping.
+ */
+ setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
+ // Add the type/uses of referred typedef/grouping to the stack.
+ addUnresolvedRecursiveReferenceToStack(linkedNode);
+ return true;
+ }
+ }
+ // If referred node can't be found return false.
+ return false;
+ }
+
+ /**
+ * Finds and resolves with import list.
+ *
+ * @return true if resolved, false otherwise
+ * @throws DataModelException a violation in data model rule
+ */
+ private boolean resolveWithImport() throws DataModelException {
+ /*
+ * Run through import list to find the referred typedef/grouping.
+ */
+ for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
+ /*
+ * Match the prefix attached to entity under resolution with the
+ * imported/included module/sub-module's prefix. If found, search
+ * for the referred typedef/grouping at the root level.
+ */
+ if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
+ YangNode linkedNode = null;
+ if (getCurrentEntityToResolveFromStack() instanceof YangType) {
+ linkedNode = findRefTypedef(yangImport.getImportedNode());
+ } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
+ linkedNode = findRefGrouping(yangImport.getImportedNode());
+ }
+ if (linkedNode != null) {
+ // Add the link to external entity.
+ addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
+ /*
+ * Update the current reference resolver to external
+ * module/sub-module containing the referred typedef/grouping.
+ */
+ setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
+ // Add the type/uses of referred typedef/grouping to the stack.
+ addUnresolvedRecursiveReferenceToStack(linkedNode);
+ return true;
+ }
+ /*
+ * If referred node can't be found at root level break for loop,
+ * and return false.
+ */
+ break;
+ }
+ }
+ // If referred node can't be found return false.
+ return false;
+ }
+
+ /**
+ * Returns referred typedef/grouping node.
+ *
+ * @return referred typedef/grouping node
+ * @throws DataModelException a violation in data model rule
+ */
+ private T getRefNode() throws DataModelException {
+ if (getCurrentEntityToResolveFromStack() instanceof YangType) {
+ YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>)
+ ((YangType<?>) getCurrentEntityToResolveFromStack()).getDataTypeExtendedInfo();
+ return (T) derivedInfo.getReferredTypeDef();
+ } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
+ return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
+ } else {
+ throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
+ }
+ }
+
+ /**
+ * Finds the referred grouping node at the root level of imported/included node.
+ *
+ * @param refNode module/sub-module node
+ * @return referred grouping
+ */
+ private YangNode findRefGrouping(YangNode refNode) {
+ YangNode tmpNode = refNode.getChild();
+ while (tmpNode != null) {
+ if (tmpNode instanceof YangGrouping) {
+ if (tmpNode.getName()
+ .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
+ return tmpNode;
+ }
+ }
+ tmpNode = tmpNode.getNextSibling();
+ }
+ return null;
+ }
+
+ /**
+ * Finds the referred typedef node at the root level of imported/included node.
+ *
+ * @param refNode module/sub-module node
+ * @return referred typedef
+ */
+ private YangNode findRefTypedef(YangNode refNode) {
+ YangNode tmpNode = refNode.getChild();
+ while (tmpNode != null) {
+ if (tmpNode instanceof YangTypeDef) {
+ if (tmpNode.getName()
+ .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
+ return tmpNode;
+ }
+ }
+ tmpNode = tmpNode.getNextSibling();
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/onosproject/yangutils/linker/impl/package-info.java b/src/main/java/org/onosproject/yangutils/linker/impl/package-info.java
index be8bb13..1d38e5a 100644
--- a/src/main/java/org/onosproject/yangutils/linker/impl/package-info.java
+++ b/src/main/java/org/onosproject/yangutils/linker/impl/package-info.java
@@ -15,6 +15,6 @@
*/
/**
- * Provide inter file and inter jar linking implementation.
+ * Provide intra/inter file and inter jar linking implementation.
*/
-package org.onosproject.yangutils.linker.impl;
\ No newline at end of file
+package org.onosproject.yangutils.linker.impl;