blob: 3400cfebdfbb138282d396660412eb4a78b06369 [file] [log] [blame]
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yangutils.linker.impl;
18
Bharat saraswale3175d32016-08-31 17:50:11 +053019import org.onosproject.yangutils.datamodel.DefaultLocationInfo;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053020import org.onosproject.yangutils.datamodel.Resolvable;
janani b0e4e8ae2016-07-13 21:06:41 +053021import org.onosproject.yangutils.datamodel.ResolvableType;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053022import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
Vidyashree Rama72719fa2016-07-15 14:06:56 +053023import org.onosproject.yangutils.datamodel.TraversalType;
janani b0e4e8ae2016-07-13 21:06:41 +053024import org.onosproject.yangutils.datamodel.YangAtomicPath;
Bharat saraswald14cbe82016-07-14 13:26:18 +053025import org.onosproject.yangutils.datamodel.YangAugment;
26import org.onosproject.yangutils.datamodel.YangAugmentableNode;
Shankara-Huawei234cd092016-07-14 11:35:34 +053027import org.onosproject.yangutils.datamodel.YangBase;
Vidyashree Ramab3670472016-08-06 15:49:56 +053028import org.onosproject.yangutils.datamodel.YangCompilerAnnotation;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053029import org.onosproject.yangutils.datamodel.YangDerivedInfo;
janani bebb143d2016-07-14 19:35:22 +053030import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053031import org.onosproject.yangutils.datamodel.YangFeature;
32import org.onosproject.yangutils.datamodel.YangFeatureHolder;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053033import org.onosproject.yangutils.datamodel.YangGrouping;
Shankara-Huawei234cd092016-07-14 11:35:34 +053034import org.onosproject.yangutils.datamodel.YangIdentity;
35import org.onosproject.yangutils.datamodel.YangIdentityRef;
Bharat saraswalaf413b82016-07-14 15:18:20 +053036import org.onosproject.yangutils.datamodel.YangIfFeature;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053037import org.onosproject.yangutils.datamodel.YangImport;
38import org.onosproject.yangutils.datamodel.YangInclude;
janani b0e4e8ae2016-07-13 21:06:41 +053039import org.onosproject.yangutils.datamodel.YangInput;
40import org.onosproject.yangutils.datamodel.YangLeaf;
41import org.onosproject.yangutils.datamodel.YangLeafList;
42import org.onosproject.yangutils.datamodel.YangLeafRef;
Vidyashree Ramab3670472016-08-06 15:49:56 +053043import org.onosproject.yangutils.datamodel.YangList;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053044import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053045import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053046import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani b0e4e8ae2016-07-13 21:06:41 +053047import org.onosproject.yangutils.datamodel.YangRelativePath;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053048import org.onosproject.yangutils.datamodel.YangResolutionInfo;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053049import org.onosproject.yangutils.datamodel.YangType;
50import org.onosproject.yangutils.datamodel.YangTypeDef;
51import org.onosproject.yangutils.datamodel.YangUses;
Bharat saraswald14cbe82016-07-14 13:26:18 +053052import org.onosproject.yangutils.datamodel.YangXPathResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053053import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053054import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
janani b0e4e8ae2016-07-13 21:06:41 +053055import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
Bharat saraswald14cbe82016-07-14 13:26:18 +053056import org.onosproject.yangutils.linker.exceptions.LinkerException;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053057
Bharat saraswal9fab16b2016-09-23 23:27:24 +053058import java.io.Serializable;
59import java.util.Iterator;
60import java.util.LinkedList;
61import java.util.List;
62import java.util.Stack;
63
64import static org.onosproject.yangutils.datamodel.ResolvableType.YANG_IDENTITYREF;
65import static org.onosproject.yangutils.datamodel.ResolvableType.YANG_LEAFREF;
Vidyashree Rama72719fa2016-07-15 14:06:56 +053066import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
67import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
68import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
69import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053070import static org.onosproject.yangutils.datamodel.YangPathArgType.ABSOLUTE_PATH;
71import static org.onosproject.yangutils.datamodel.YangPathArgType.RELATIVE_PATH;
72import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.getErrorMsg;
janani bebb143d2016-07-14 19:35:22 +053073import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053074import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
75import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
76import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
77import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053078import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNDEFINED;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053079import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053080import static org.onosproject.yangutils.datamodel.utils.YangConstructType.PATH_DATA;
Bharat saraswal94844d62016-10-13 13:28:03 +053081import static org.onosproject.yangutils.linker.impl.XpathLinkingTypes.AUGMENT_LINKING;
82import static org.onosproject.yangutils.linker.impl.XpathLinkingTypes.LEAF_REF_LINKING;
Bharat saraswald14cbe82016-07-14 13:26:18 +053083import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
janani b3a3e3262016-10-19 00:23:28 +053084import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.fillPathPredicates;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053085import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getErrorInfoForLinker;
86import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getLeafRefErrorInfo;
janani bebb143d2016-07-14 19:35:22 +053087import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
88import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getValidNodeIdentifier;
89import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.skipInvalidDataNodes;
janani bebb143d2016-07-14 19:35:22 +053090import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053091import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_FIND_ANNOTATION;
92import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_FIND_LEAD_INFO_HOLDER;
93import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_LINK;
Bharat saraswalaf413b82016-07-14 15:18:20 +053094import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053095import static org.onosproject.yangutils.utils.UtilConstants.INVALID_ENTITY;
96import static org.onosproject.yangutils.utils.UtilConstants.INVALID_LINKER_STATE;
97import static org.onosproject.yangutils.utils.UtilConstants.INVALID_RESOLVED_ENTITY;
98import static org.onosproject.yangutils.utils.UtilConstants.INVALID_TARGET;
99import static org.onosproject.yangutils.utils.UtilConstants.INVALID_TREE;
janani b0e4e8ae2016-07-13 21:06:41 +0530100import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530101import static org.onosproject.yangutils.utils.UtilConstants.LINKER_ERROR;
janani bebb143d2016-07-14 19:35:22 +0530102import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530103import static org.onosproject.yangutils.utils.UtilConstants.UNRESOLVABLE;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530104
105/**
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530106 * Represents implementation of resolution object which will be resolved by
107 * linker.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530108 *
109 * @param <T> type of resolution entity uses / type
110 */
Bharat saraswale3175d32016-08-31 17:50:11 +0530111public class YangResolutionInfoImpl<T> extends DefaultLocationInfo
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530112 implements YangResolutionInfo<T>, Serializable {
113
114 private static final long serialVersionUID = 806201658L;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530115
116 /**
117 * Information about the entity that needs to be resolved.
118 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530119 private YangEntityToResolveInfoImpl<T> entityToResolveInfo;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530120
121 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530122 * Current module/sub-module reference, will be used in inter-file/
123 * inter-jar scenario to get the import/include list.
124 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530125 private YangReferenceResolver curRefResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530126
127 /**
128 * Stack for type/uses is maintained for hierarchical references, this is
129 * used during resolution.
130 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530131 private Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530132
133 /**
134 * It is private to ensure the overloaded method be invoked to create an
135 * object.
136 */
137 @SuppressWarnings("unused")
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530138 private YangResolutionInfoImpl() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530139 }
140
141 /**
142 * Creates a resolution information object with all the inputs.
143 *
144 * @param dataNode current parsable data node
145 * @param holderNode parent YANG node
146 * @param lineNumber error line number
147 * @param charPositionInLine error character position in line
148 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530149 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber,
150 int charPositionInLine) {
151 entityToResolveInfo = new YangEntityToResolveInfoImpl<>();
152 entityToResolveInfo.setEntityToResolve(dataNode);
153 entityToResolveInfo.setHolderOfEntityToResolve(holderNode);
154 setLineNumber(lineNumber);
155 setCharPosition(charPositionInLine);
156 partialResolvedStack = new Stack<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530157 }
158
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530159 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530160 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
161 throws DataModelException {
162
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530163 curRefResolver = dataModelRootNode;
164 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530165 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
166 * YANG leafref or YANG base or YANG identityref.
167 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530168 T entityToResolve = entityToResolveInfo.getEntityToResolve();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530169
170 // Check if linking is already done
171 if (entityToResolve instanceof Resolvable) {
172 Resolvable resolvable = (Resolvable) entityToResolve;
173 if (resolvable.getResolvableStatus() == RESOLVED) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530174 /*
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530175 * entity is already resolved, so nothing to do
176 */
177 return;
178 }
179 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530180 throw new DataModelException(LINKER_ERROR);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530181 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530182 // Push the initial entity to resolve in stack.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530183 addInPartialResolvedStack(entityToResolveInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530184 linkAndResolvePartialResolvedStack();
janani b0e4e8ae2016-07-13 21:06:41 +0530185 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530186 }
187
188 /**
189 * Resolves linking with ancestors.
190 *
191 * @throws DataModelException a violation of data model rules
192 */
193 private void linkAndResolvePartialResolvedStack()
194 throws DataModelException {
195
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530196 while (!partialResolvedStack.isEmpty()) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530197 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530198 * Current node to resolve, it can be a YANG type or YANG uses or
199 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
200 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530201 T entityToResolve = getCurEntityToResolveFromStack();
202 if (!(entityToResolve instanceof Resolvable)) {
203 throw new DataModelException(LINKER_ERROR);
204 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530205 // Check if linking is already done
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530206 Resolvable resolvable = (Resolvable) entityToResolve;
207 switch (resolvable.getResolvableStatus()) {
208 case RESOLVED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530209 /*
210 * If the entity is already resolved in the stack, then pop
211 * it and continue with the remaining stack elements to
212 * resolve
213 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530214 partialResolvedStack.pop();
215 break;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530216
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530217 case LINKED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530218 /*
219 * If the top of the stack is already linked then resolve
220 * the references and pop the entity and continue with
221 * remaining stack elements to resolve.
222 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530223 resolveTopOfStack();
224 partialResolvedStack.pop();
225 break;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530226
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530227 case INTRA_FILE_RESOLVED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530228 /*
229 * Pop the top of the stack.
230 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530231 partialResolvedStack.pop();
232 break;
233
234 case UNRESOLVED:
235 linkTopOfStackReferenceUpdateStack();
236
237 if (resolvable.getResolvableStatus() == UNRESOLVED) {
238 // If current entity is still not resolved, then
239 // linking/resolution has failed.
240 DataModelException ex =
241 new DataModelException
242 (getErrorInfoForLinker(resolvable));
243 ex.setLine(getLineNumber());
244 ex.setCharPosition(getCharPosition());
245 throw ex;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530246 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530247 break;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530248
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530249 default:
250 throw new DataModelException(INVALID_LINKER_STATE);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530251 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530252 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530253 }
254
255 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530256 * Adds the leafref/identityref type to the type, which has derived type referring to
257 * typedef with leafref/identityref type.
janani b0e4e8ae2016-07-13 21:06:41 +0530258 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530259 private void addDerivedRefTypeToRefTypeResolutionList()
260 throws DataModelException {
janani b0e4e8ae2016-07-13 21:06:41 +0530261
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530262 YangNode refNode = entityToResolveInfo.getHolderOfEntityToResolve();
263 YangType yangType = getValidateResolvableType();
janani b0e4e8ae2016-07-13 21:06:41 +0530264
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530265 if (yangType == null) {
janani b0e4e8ae2016-07-13 21:06:41 +0530266 return;
267 }
268
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530269 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType
270 .getDataTypeExtendedInfo();
janani b0e4e8ae2016-07-13 21:06:41 +0530271
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530272 YangDataTypes dataType = derivedInfo.getEffectiveBuiltInType();
Vidyashree Ramab3670472016-08-06 15:49:56 +0530273 // If the derived types referred type is not leafref/identityref return
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530274 if (dataType != YangDataTypes.LEAFREF &&
275 dataType != YangDataTypes.IDENTITYREF) {
janani b0e4e8ae2016-07-13 21:06:41 +0530276 return;
277 }
278
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530279 T extendedInfo = (T) derivedInfo.getReferredTypeDef()
280 .getTypeDefBaseType().getDataTypeExtendedInfo();
janani b0e4e8ae2016-07-13 21:06:41 +0530281
282 while (extendedInfo instanceof YangDerivedInfo) {
283 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530284 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef()
285 .getTypeDefBaseType().getDataTypeExtendedInfo();
janani b0e4e8ae2016-07-13 21:06:41 +0530286 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530287
janani b0e4e8ae2016-07-13 21:06:41 +0530288 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530289 * Backup the derived types leafref/identityref info, delete all the info in current type,
290 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
291 * create a leafref/identityref resolution info using the current resolution info and
292 * add to leafref/identityref resolution list.
janani b0e4e8ae2016-07-13 21:06:41 +0530293 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530294 if (dataType == YangDataTypes.LEAFREF) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530295 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530296 addRefTypeInfo(YangDataTypes.LEAFREF, LEAFREF, extendedInfo,
297 yangType, refNode, YANG_LEAFREF);
janani b3a3e3262016-10-19 00:23:28 +0530298 leafRefInTypeDef.setParentNode(refNode);
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530299 } else {
300 addRefTypeInfo(YangDataTypes.IDENTITYREF, IDENTITYREF, extendedInfo,
301 yangType, refNode, YANG_IDENTITYREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530302 }
janani b0e4e8ae2016-07-13 21:06:41 +0530303 }
304
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530305 //Validates entity to resolve for YANG type and returns type
306 private YangType getValidateResolvableType() {
307 YangNode refNode = entityToResolveInfo.getHolderOfEntityToResolve();
308 T entity = entityToResolveInfo.getEntityToResolve();
309 // If holder is typedef return.
310 if (!(refNode instanceof YangTypeDef) && entity instanceof YangType) {
311 YangType yangType = (YangType) entity;
312
313 // If type is not resolved return.
314 if (yangType.getResolvableStatus() == RESOLVED) {
315 return (YangType) entity;
316 }
317 }
318 return null;
319 }
320
321 /**
322 * Adds referred type(leafref/identityref) info to resolution list.
323 *
324 * @param type data type
325 * @param typeName type name
326 * @param info extended info
327 * @param yangType YANG type
328 * @param refNode referred node
329 * @param resType resolution type
330 * @throws DataModelException when fails to do data model operations
331 */
332 private void addRefTypeInfo(YangDataTypes type, String typeName, T info,
333 YangType yangType, YangNode refNode,
334 ResolvableType resType) throws DataModelException {
335 yangType.resetYangType();
336 yangType.setResolvableStatus(RESOLVED);
337 yangType.setDataType(type);
338 yangType.setDataTypeName(typeName);
339 yangType.setDataTypeExtendedInfo(info);
340 ((Resolvable) info).setResolvableStatus(UNRESOLVED);
341 YangResolutionInfoImpl resolutionInfoImpl
342 = new YangResolutionInfoImpl<>(info, refNode,
343 getLineNumber(), getCharPosition());
344 curRefResolver.addToResolutionList(resolutionInfoImpl, resType);
345 curRefResolver.resolveSelfFileLinking(resType);
346 }
347
janani b0e4e8ae2016-07-13 21:06:41 +0530348 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530349 * Resolves the current entity in the stack.
350 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530351 private void resolveTopOfStack()
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530352 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530353 T entity = getCurEntityToResolveFromStack();
354 List<T> entityToResolve = (List<T>) ((Resolvable) entity).resolve();
janani bebb143d2016-07-14 19:35:22 +0530355 if (entityToResolve != null && !entityToResolve.isEmpty()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530356 for (T anEntityToResolve : entityToResolve) {
357 addUnresolvedEntitiesToResolutionList(anEntityToResolve);
janani bebb143d2016-07-14 19:35:22 +0530358 }
359 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530360 if (((Resolvable) entity).getResolvableStatus() != INTRA_FILE_RESOLVED &&
361 ((Resolvable) entity).getResolvableStatus() != UNDEFINED) {
janani b0e4e8ae2016-07-13 21:06:41 +0530362 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530363 ((Resolvable) entity).setResolvableStatus(RESOLVED);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530364 }
365 }
366
367 /**
janani bebb143d2016-07-14 19:35:22 +0530368 * Adds the unresolved entities to the resolution list.
369 *
370 * @param entityToResolve entity to resolve
371 * @throws DataModelException a violation of data model rules
372 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530373 private void addUnresolvedEntitiesToResolutionList(T entityToResolve)
374 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530375 if (entityToResolve instanceof YangEntityToResolveInfoImpl) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530376 YangEntityToResolveInfoImpl entityToResolveInfo
377 = (YangEntityToResolveInfoImpl) entityToResolve;
janani bebb143d2016-07-14 19:35:22 +0530378 if (entityToResolveInfo.getEntityToResolve() instanceof YangLeafRef) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530379 YangLeafRef leafref = (YangLeafRef) entityToResolveInfo
380 .getEntityToResolve();
381 YangNode parentNodeOfLeafref = entityToResolveInfo
382 .getHolderOfEntityToResolve();
janani b3a3e3262016-10-19 00:23:28 +0530383 leafref.setParentNode(parentNodeOfLeafref);
janani bebb143d2016-07-14 19:35:22 +0530384 if (leafref.getResolvableStatus() == UNRESOLVED) {
385 leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
386 }
janani bebb143d2016-07-14 19:35:22 +0530387 }
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530388
389 // Add resolution information to the list.
390 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530391 entityToResolveInfo.getEntityToResolve(),
392 entityToResolveInfo.getHolderOfEntityToResolve(),
393 entityToResolveInfo.getLineNumber(),
394 entityToResolveInfo.getCharPosition());
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530395 addResolutionInfo(resolutionInfoImpl);
janani bebb143d2016-07-14 19:35:22 +0530396 }
397 }
398
399 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530400 * Resolves linking for a node child and siblings.
401 *
402 * @throws DataModelException data model error
403 */
404 private void linkTopOfStackReferenceUpdateStack()
405 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530406 T entity = getCurEntityToResolveFromStack();
407 if (entity instanceof YangLeafRef) {
408 ((Resolvable) entity).setResolvableStatus(INTRA_FILE_RESOLVED);
janani bebb143d2016-07-14 19:35:22 +0530409 return;
410 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530411 /*
412 * Check if self file reference is there, this will not check for the
413 * scenario when prefix is not present and type/uses is present in
414 * sub-module from include list.
415 */
416 if (!isCandidateForSelfFileReference()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530417 ((Resolvable) entity).setResolvableStatus(INTRA_FILE_RESOLVED);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530418 return;
419 }
420
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530421 /*
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530422 * Try to resolve the top of the stack and update partial resolved stack
423 * if there is recursive references
424 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530425 YangNode ancestorRefNode = partialResolvedStack.peek()
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530426 .getHolderOfEntityToResolve();
427
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530428 if (entity instanceof YangIfFeature) {
429 resolveSelfFileLinkingForIfFeature(ancestorRefNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530430 return;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530431 }
432 if (entity instanceof YangIdentityRef || entity instanceof YangBase) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530433 resolveSelfFileLinkingForBaseAndIdentityref();
434 return;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530435 }
436 YangType type = null;
437 if (entity instanceof YangType) {
438 type = (YangType) entity;
439 }
440 /*
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530441 * Traverse up in the ancestor tree to check if the referred node is
442 * defined
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530443 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530444 while (ancestorRefNode != null) {
445 /*
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530446 * Check for the referred node defined in a ancestor scope
447 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530448 YangNode curRefNode = ancestorRefNode.getChild();
449 if (isReferredNodeInSiblingListProcessed(curRefNode)) {
450 return;
451 }
452 ancestorRefNode = ancestorRefNode.getParent();
453 if (type != null && ancestorRefNode != null) {
454 if (ancestorRefNode.getParent() == null) {
455 type.setTypeNotResolvedTillRootNode(true);
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530456 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530457 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530458 }
459
460 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530461 * In case prefix is not present or it's self prefix it's a candidate for inter-file
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530462 * resolution via include list.
463 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530464 if (getRefPrefix() == null ||
465 getRefPrefix().contentEquals(curRefResolver.getPrefix())) {
466 ((Resolvable) entity).setResolvableStatus(INTRA_FILE_RESOLVED);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530467 }
468 }
469
470 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530471 * Resolves self file linking for base/identityref.
472 *
473 * @throws DataModelException a violation of data model rules
474 */
475 private void resolveSelfFileLinkingForBaseAndIdentityref()
476 throws DataModelException {
477
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530478 boolean refIdentity = false;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530479 String nodeName = null;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530480 T entity = getCurEntityToResolveFromStack();
481 if (entity instanceof YangIdentityRef) {
482 nodeName = ((YangIdentityRef) entity).getName();
483 } else if (entity instanceof YangBase) {
484 nodeName = ((YangBase) entity).getBaseIdentifier().getName();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530485 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530486 if (curRefResolver instanceof RpcNotificationContainer) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530487 // Sends list of nodes for finding the target identity.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530488 refIdentity = isIdentityReferenceFound(nodeName, (YangNode) curRefResolver);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530489 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530490 if (refIdentity) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530491 return;
492 }
493
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530494 /*
495 * In case prefix is not present or it's self prefix it's a candidate for inter-file
496 * resolution via include list.
497 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530498 if (getRefPrefix() == null || getRefPrefix()
499 .contentEquals(curRefResolver.getPrefix())) {
500 ((Resolvable) entity).setResolvableStatus(INTRA_FILE_RESOLVED);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530501 }
502 }
503
504 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530505 * Resolves self file linking for if-feature.
506 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530507 * @param ancestorRefNode if-feature holder node
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530508 * @throws DataModelException DataModelException a violation of data model
509 * rules
510 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530511 private void resolveSelfFileLinkingForIfFeature(YangNode ancestorRefNode)
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530512 throws DataModelException {
513
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530514 YangFeatureHolder featureHolder = getFeatureHolder(ancestorRefNode);
515 YangNode curRefNode = (YangNode) featureHolder;
516 if (isReferredNode(curRefNode)) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530517
518 // Adds reference link of entity to the node under resolution.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530519 addReferredEntityLink(curRefNode, LINKED);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530520
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530521 /*
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530522 * resolve the reference and update the partial resolution stack
523 * with any further recursive references
524 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530525 addUnresolvedRecursiveReferenceToStack(curRefNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530526 return;
527 }
528
529 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530530 * In case prefix is not present or it's self prefix it's a candidate for inter-file
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530531 * resolution via include list.
532 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530533 if (getRefPrefix() == null || getRefPrefix()
534 .contentEquals(curRefResolver.getPrefix())) {
535 ((Resolvable) getCurEntityToResolveFromStack())
536 .setResolvableStatus(INTRA_FILE_RESOLVED);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530537 }
538 }
539
janani b0e4e8ae2016-07-13 21:06:41 +0530540 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530541 * Returns the status of the referred identity found for base/identityref.
542 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530543 * @param nodeName the name of the base node
544 * identifier/identityref node identifier
545 * @param ancestorRefNode the parent node of base/identityref
Shankara-Huawei234cd092016-07-14 11:35:34 +0530546 * @return status of referred base/identityref
547 * @throws DataModelException a violation of data model rules
548 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530549 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorRefNode)
Shankara-Huawei234cd092016-07-14 11:35:34 +0530550 throws DataModelException {
551
552 // When child is not present return.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530553 if (ancestorRefNode.getChild() == null) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530554 return false;
555 }
556
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530557 ancestorRefNode = ancestorRefNode.getChild();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530558
559 // Checks all the siblings under the node and returns the matched node.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530560 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorRefNode,
561 nodeName);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530562
563 if (nodeFound != null) {
564 // Adds reference link of entity to the node under resolution.
565 addReferredEntityLink(nodeFound, LINKED);
566
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530567 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530568 * resolve the reference and update the partial resolution stack with any further recursive references
569 */
570 addUnresolvedRecursiveReferenceToStack(nodeFound);
571 return true;
572 }
573
574 return false;
575 }
576
577 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530578 * Adds the unresolved constructs to stack which has to be resolved for leafref.
579 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530580 * @param leavesInfo YANG leaf or leaf list which holds the type
581 * @param ancestorRefNode holder of the YANG leaf or leaf list
janani b0e4e8ae2016-07-13 21:06:41 +0530582 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530583 private void addUnResolvedLeafRefTypeToStack(T leavesInfo, YangNode ancestorRefNode) {
janani b0e4e8ae2016-07-13 21:06:41 +0530584
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530585 YangType refType;
586 T extendedInfo;
587 if (leavesInfo instanceof YangLeaf) {
588 YangLeaf leaf = (YangLeaf) leavesInfo;
589 refType = leaf.getDataType();
janani b0e4e8ae2016-07-13 21:06:41 +0530590 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530591 YangLeafList leafList = (YangLeafList) leavesInfo;
592 refType = leafList.getDataType();
593 }
594 extendedInfo = (T) refType.getDataTypeExtendedInfo();
595 addUnResolvedTypeDataToStack(refType, ancestorRefNode, extendedInfo);
596 }
597
598 //Adds unresolved type info to stack.
599 private void addUnResolvedTypeDataToStack(YangType refType, YangNode
600 ancestorRefNode, T extendedInfo) {
601 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedLeafRef =
602 new YangEntityToResolveInfoImpl<>();
603 YangEntityToResolveInfoImpl<YangType<?>> unResolvedTypeDef =
604 new YangEntityToResolveInfoImpl<>();
605 if (refType.getDataType() == YangDataTypes.LEAFREF) {
606 unResolvedLeafRef.setEntityToResolve((YangLeafRef<?>) extendedInfo);
607 unResolvedLeafRef.setHolderOfEntityToResolve(ancestorRefNode);
608 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedLeafRef);
609 } else if (refType.getDataType() == YangDataTypes.DERIVED) {
610 unResolvedTypeDef.setEntityToResolve(refType);
611 unResolvedTypeDef.setHolderOfEntityToResolve(ancestorRefNode);
612 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedTypeDef);
janani b0e4e8ae2016-07-13 21:06:41 +0530613 }
614 }
615
616 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530617 * Returns feature holder(module/sub-module node) .
618 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530619 * @param ancestorRefNode if-feature holder node
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530620 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530621 private YangFeatureHolder getFeatureHolder(YangNode ancestorRefNode) {
622 while (ancestorRefNode != null) {
623 if (ancestorRefNode instanceof YangFeatureHolder) {
624 return (YangFeatureHolder) ancestorRefNode;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530625 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530626 ancestorRefNode = ancestorRefNode.getParent();
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530627 }
628 return null;
629 }
630
631 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530632 * Checks if the reference in self file or in external file.
633 *
634 * @return true if self file reference, false otherwise
635 * @throws DataModelException a violation of data model rules
636 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530637 private boolean isCandidateForSelfFileReference()
638 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530639 String prefix = getRefPrefix();
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530640 return prefix == null || prefix.contentEquals(curRefResolver.getPrefix());
janani b0e4e8ae2016-07-13 21:06:41 +0530641 }
642
643 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530644 * Checks for the referred parent node for the base/identity.
645 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530646 * @param refNode potential referred node
647 * @return the referred parent node of base/identity.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530648 * @throws DataModelException data model errors
649 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530650 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode refNode,
651 String refName)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530652 throws DataModelException {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530653
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530654 while (refNode != null) {
655 if (refNode instanceof YangIdentity) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530656 // Check if the potential referred node is the actual referred node
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530657 if (isReferredNodeForIdentity(refNode, refName)) {
658 return refNode;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530659 }
660 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530661 refNode = refNode.getNextSibling();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530662 }
663 return null;
664 }
665
666 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530667 * Checks if the current reference node name and the name in the base/identityref base are equal.
668 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530669 * @param curRefNode the node where the reference is pointed
670 * @param name name of the base in the base/identityref base
Shankara-Huawei234cd092016-07-14 11:35:34 +0530671 * @return status of the match between the name
672 * @throws DataModelException a violation of data model rules
673 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530674 private boolean isReferredNodeForIdentity(YangNode curRefNode, String name)
Shankara-Huawei234cd092016-07-14 11:35:34 +0530675 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530676 T entity = getCurEntityToResolveFromStack();
677 if (entity instanceof YangIdentityRef || entity instanceof YangBase) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530678
679 //Check if name of node name matches with the current reference node.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530680 return curRefNode.getName().contentEquals(name);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530681 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530682 throw new DataModelException(getErrorMsg(
683 INVALID_ENTITY, curRefNode.getName(), curRefNode.getLineNumber(),
684 curRefNode.getCharPosition(), curRefNode.getFileName()));
Shankara-Huawei234cd092016-07-14 11:35:34 +0530685 }
686 }
687
688 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530689 * Checks for the referred node defined in a ancestor scope.
690 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530691 * @param refNode potential referred node
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530692 * @return status of resolution and updating the partial resolved stack with
693 * the any recursive references
janani b0e4e8ae2016-07-13 21:06:41 +0530694 * @throws DataModelException a violation of data model rules
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530695 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530696 private boolean isReferredNodeInSiblingListProcessed(YangNode refNode)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530697 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530698 while (refNode != null) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530699
700 // Check if the potential referred node is the actual referred node
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530701 if (isReferredNode(refNode)) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530702
703 // Adds reference link of entity to the node under resolution.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530704 addReferredEntityLink(refNode, LINKED);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530705
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530706 /*
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530707 * resolve the reference and update the partial resolution stack
708 * with any further recursive references
709 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530710 addUnresolvedRecursiveReferenceToStack(refNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530711
712 /*
713 * return true, since the reference is linked and any recursive
714 * unresolved references is added to the stack
715 */
716 return true;
717 }
718
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530719 refNode = refNode.getNextSibling();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530720 }
721 return false;
722 }
723
724 /**
725 * Checks if the potential referred node is the actual referred node.
726 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530727 * @param refNode typedef/grouping node
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530728 * @return true if node is of resolve type otherwise false
729 * @throws DataModelException a violation of data model rules
730 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530731 private boolean isReferredNode(YangNode refNode)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530732 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530733 T entity = getCurEntityToResolveFromStack();
734 if (entity instanceof YangType) {
735 if (refNode instanceof YangTypeDef) {
736 return isNodeNameSameAsResolutionInfoName(refNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530737 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530738 } else if (entity instanceof YangUses) {
739 if (refNode instanceof YangGrouping) {
740 return isNodeNameSameAsResolutionInfoName(refNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530741 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530742 } else if (entity instanceof YangIfFeature) {
743 if (refNode instanceof YangFeatureHolder) {
744 return isNodeNameSameAsResolutionInfoName(refNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530745 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530746 } else if (entity instanceof YangBase || entity instanceof YangIdentityRef) {
747 if (refNode instanceof YangIdentity) {
748 return isNodeNameSameAsResolutionInfoName(refNode);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530749 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530750 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530751 throw new DataModelException(getErrorMsg(
752 LINKER_ERROR, refNode.getName(), refNode.getLineNumber(),
753 refNode.getCharPosition(), refNode.getFileName()));
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530754 }
755 return false;
756 }
757
758 /**
759 * Checks if node name is same as name in resolution info, i.e. name of
760 * typedef/grouping is same as name of type/uses.
761 *
762 * @param node typedef/grouping node
763 * @return true if node name is same as name in resolution info, otherwise
764 * false
765 * @throws DataModelException a violation of data model rules
766 */
767
768 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
769 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530770 T entity = getCurEntityToResolveFromStack();
771 if (entity instanceof YangType) {
772 return node.getName().contentEquals(((YangType<?>) entity)
773 .getDataTypeName());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530774 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530775 if (entity instanceof YangUses) {
776 return node.getName().contentEquals(((YangUses) entity).getName());
777 }
778 if (entity instanceof YangIfFeature) {
779 return isFeatureDefinedInNode(node);
780 }
781 if (entity instanceof YangBase) {
782 return node.getName().contentEquals(((
783 YangBase) entity).getBaseIdentifier().getName());
784 }
785 if (entity instanceof YangIdentityRef) {
786 return node.getName().contentEquals(((YangIdentityRef) entity).getName());
787 }
788 throw new DataModelException(getErrorMsg(
789 INVALID_RESOLVED_ENTITY, node.getName(), node.getLineNumber(),
790 node.getCharPosition(), node.getFileName()));
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530791 }
792
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530793 private boolean isFeatureDefinedInNode(YangNode node) {
794 T entity = getCurEntityToResolveFromStack();
795 YangNodeIdentifier ifFeature = ((YangIfFeature) entity).getName();
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530796 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
797 if (featureList != null && !featureList.isEmpty()) {
798 Iterator<YangFeature> iterator = featureList.iterator();
799 while (iterator.hasNext()) {
800 YangFeature feature = iterator.next();
801 if (ifFeature.getName().equals(feature.getName())) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530802 ((YangIfFeature) entity).setReferredFeature(feature);
803 ((YangIfFeature) entity).setReferredFeatureHolder(node);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530804 return true;
805 }
806 }
807 }
808 return false;
809 }
810
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530811 /**
812 * Adds reference of grouping/typedef in uses/type.
813 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530814 * @param refNode grouping/typedef node being referred
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530815 * @param linkedStatus linked status if success.
816 * @throws DataModelException a violation of data model rules
817 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530818 private void addReferredEntityLink(YangNode refNode, ResolvableStatus linkedStatus)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530819 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530820 T entity = getCurEntityToResolveFromStack();
821 if (entity instanceof YangType) {
822 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((
823 YangType<?>) entity).getDataTypeExtendedInfo();
824 derivedInfo.setReferredTypeDef((YangTypeDef) refNode);
825 } else if (entity instanceof YangUses) {
826 ((YangUses) entity).setRefGroup((YangGrouping) refNode);
827 } else if (entity instanceof YangBase) {
828 ((YangBase) entity).setReferredIdentity((YangIdentity) refNode);
829 } else if (entity instanceof YangIdentityRef) {
830 ((YangIdentityRef) entity).setReferredIdentity((YangIdentity) refNode);
831 } else if (!(entity instanceof YangIfFeature) &&
832 !(entity instanceof YangLeafRef)) {
833 throw new DataModelException(getErrorMsg(
834 LINKER_ERROR, refNode.getName(), refNode.getLineNumber(),
835 refNode.getCharPosition(), refNode.getFileName()));
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530836 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530837 // Sets the resolution status in inside the type/uses.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530838 ((Resolvable) entity).setResolvableStatus(linkedStatus);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530839 }
840
841 /**
842 * Checks if type/grouping has further reference to typedef/ unresolved
843 * uses. Add it to the partial resolve stack and return the status of
844 * addition to stack.
845 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530846 * @param refNode grouping/typedef node
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530847 * @throws DataModelException a violation of data model rules
848 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530849 private void addUnresolvedRecursiveReferenceToStack(YangNode refNode)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530850 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530851 T entity = getCurEntityToResolveFromStack();
852 if (entity instanceof YangType) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530853
854 //Checks if typedef type is derived
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530855 if (((YangTypeDef) refNode).getTypeDefBaseType()
856 .getDataType() == YangDataTypes.DERIVED) {
857 addEntityToStack((T) ((YangTypeDef) refNode).getTypeDefBaseType(),
858 refNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530859 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530860 } else if (entity instanceof YangUses) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530861 /*
862 * Search if the grouping has any un resolved uses child, if so
863 * return true, else return false.
864 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530865 addUnResolvedUsesToStack(refNode);
866 } else if (entity instanceof YangIfFeature) {
867 addUnResolvedIfFeatureToStack(refNode);
868 } else if (entity instanceof YangLeafRef) {
janani b0e4e8ae2016-07-13 21:06:41 +0530869 // do nothing , referred node is already set
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530870 throw new DataModelException(getErrorMsg(
871 INVALID_RESOLVED_ENTITY, refNode.getName(), refNode.getLineNumber(),
872 refNode.getCharPosition(), refNode.getFileName()));
873 } else if (entity instanceof YangBase || entity instanceof YangIdentityRef) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530874
875 //Search if the identity has any un resolved base, if so return true, else return false.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530876 addUnResolvedBaseToStack(refNode);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530877 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530878 throw new DataModelException(getErrorMsg(
879 LINKER_ERROR, refNode.getName(), refNode.getLineNumber(),
880 refNode.getCharPosition(), refNode.getFileName()));
Bharat saraswale3175d32016-08-31 17:50:11 +0530881
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530882 }
883 }
884
885 /**
886 * Returns if there is any unresolved uses in grouping.
887 *
888 * @param node grouping/typedef node
889 */
890 private void addUnResolvedUsesToStack(YangNode node) {
891
Vidyashree Ramab3670472016-08-06 15:49:56 +0530892 //Search the grouping node's children for presence of uses node.
Vidyashree Rama72719fa2016-07-15 14:06:56 +0530893 TraversalType curTraversal = ROOT;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530894 YangNode curNode = node.getChild();
895 while (curNode != null) {
Vidyashree Rama72719fa2016-07-15 14:06:56 +0530896 if (curNode.getName().equals(node.getName())) {
897 // if we have traversed all the child nodes, then exit from loop
898 return;
899 }
900
901 // if child nodes has uses, then add it to resolution stack
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530902 if (curNode instanceof YangUses) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530903 addEntityToStack((T) curNode, node);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530904 }
Vidyashree Rama72719fa2016-07-15 14:06:56 +0530905
906 // Traversing all the child nodes of grouping
907 if (curTraversal != PARENT && curNode.getChild() != null) {
908 curTraversal = CHILD;
909 curNode = curNode.getChild();
910 } else if (curNode.getNextSibling() != null) {
911 curTraversal = SIBILING;
912 curNode = curNode.getNextSibling();
913 } else {
914 curTraversal = PARENT;
915 curNode = curNode.getParent();
916 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530917 }
918 }
919
920 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530921 * Returns if there is any unresolved if-feature in feature.
922 *
923 * @param node module/submodule node
924 */
925 private void addUnResolvedIfFeatureToStack(YangNode node) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530926 YangFeature refFeature = ((YangIfFeature) getCurEntityToResolveFromStack())
927 .getReferredFeature();
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530928 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
929 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
930 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
931 while (ifFeatureIterator.hasNext()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530932 addEntityToStack((T) ifFeatureIterator.next(), node);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530933 }
934 }
935 }
936
937 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530938 * Returns if there is any unresolved base in identity.
939 *
940 * @param node module/submodule node
941 */
942 private void addUnResolvedBaseToStack(YangNode node) {
943
944 YangIdentity curNode = (YangIdentity) node;
945 if (curNode.getBaseNode() != null) {
946 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530947 addEntityToStack((T) curNode.getBaseNode(), node);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530948 }
949 }
950 }
951
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530952 private void addEntityToStack(T entity, YangNode holder) {
953 YangEntityToResolveInfoImpl<T> unResolvedEntityInfo =
954 new YangEntityToResolveInfoImpl<>();
955 unResolvedEntityInfo.setEntityToResolve(entity);
956 unResolvedEntityInfo.setHolderOfEntityToResolve(holder);
957 addInPartialResolvedStack(unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530958 }
959
960 /**
961 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
962 *
963 * @param partialResolvedInfo partial resolved YANG construct stack
964 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530965 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530966 partialResolvedStack.push(partialResolvedInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530967 }
968
969 /**
970 * Retrieves the next entity in the stack that needs to be resolved. It is
971 * assumed that the caller ensures that the stack is not empty.
972 *
973 * @return next entity in the stack that needs to be resolved
974 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530975 private T getCurEntityToResolveFromStack() {
976 return partialResolvedStack.peek().getEntityToResolve();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530977 }
978
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530979 @Override
980 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530981 return entityToResolveInfo;
982 }
983
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530984 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530985 public void linkInterFile(YangReferenceResolver dataModelRootNode)
986 throws DataModelException {
987
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530988 curRefResolver = dataModelRootNode;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530989
990 // Current node to resolve, it can be a YANG type or YANG uses.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530991 T entityToResolve = entityToResolveInfo.getEntityToResolve();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530992
993 // Check if linking is already done
994 if (entityToResolve instanceof Resolvable) {
995 Resolvable resolvable = (Resolvable) entityToResolve;
996 if (resolvable.getResolvableStatus() == RESOLVED) {
997 return;
998 }
999 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301000 throw new DataModelException(UNRESOLVABLE);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301001 }
1002
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301003 if (entityToResolve instanceof YangXPathResolver &&
1004 !(entityToResolve instanceof YangLeafRef)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +05301005 //Process x-path linking.
janani bebb143d2016-07-14 19:35:22 +05301006 processXPathLinking(entityToResolve, dataModelRootNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301007
Bharat saraswald14cbe82016-07-14 13:26:18 +05301008 } else {
Bharat saraswald14cbe82016-07-14 13:26:18 +05301009 // Push the initial entity to resolve in stack.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301010 addInPartialResolvedStack(entityToResolveInfo);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301011 // Inter file linking and resolution.
1012 linkInterFileAndResolve();
Bharat saraswald14cbe82016-07-14 13:26:18 +05301013 addDerivedRefTypeToRefTypeResolutionList();
1014 }
1015 }
1016
1017 /**
1018 * Process x-path linking for augment and leaf-ref.
1019 *
janani bebb143d2016-07-14 19:35:22 +05301020 * @param entityToResolve entity to resolve
1021 * @param root root node
janani b3a3e3262016-10-19 00:23:28 +05301022 * @throws DataModelException if there is a data model error
Bharat saraswald14cbe82016-07-14 13:26:18 +05301023 */
janani bebb143d2016-07-14 19:35:22 +05301024 private void processXPathLinking(T entityToResolve,
janani b3a3e3262016-10-19 00:23:28 +05301025 YangReferenceResolver root)
1026 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301027
Bharat saraswald14cbe82016-07-14 13:26:18 +05301028 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
janani bebb143d2016-07-14 19:35:22 +05301029
Bharat saraswald14cbe82016-07-14 13:26:18 +05301030 if (entityToResolve instanceof YangAugment) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301031 YangNode targetNode;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301032 YangAugment augment = (YangAugment) entityToResolve;
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301033 targetNode = xPathLinker
Bharat saraswal94844d62016-10-13 13:28:03 +05301034 .processXpathLinking(augment.getTargetNode(), (YangNode)
1035 root, AUGMENT_LINKING);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301036 if (targetNode != null) {
1037 if (targetNode instanceof YangAugmentableNode) {
1038 detectCollisionForAugmentedNode(targetNode, augment);
1039 ((YangAugmentableNode) targetNode).addAugmentation(augment);
1040 augment.setAugmentedNode(targetNode);
Vidyashree Ramab20ba9e2016-09-02 14:12:25 +05301041 setAugmentedFlagInAncestors(targetNode);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301042 Resolvable resolvable = (Resolvable) entityToResolve;
1043 resolvable.setResolvableStatus(RESOLVED);
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301044 if (targetNode instanceof YangInput) {
1045 xPathLinker.addInModuleIfInput(augment, (YangNode) root);
1046 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301047 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301048 throw new LinkerException(getErrorMsg(
1049 INVALID_TARGET + targetNode.getNodeType(),
1050 augment.getName(), augment.getLineNumber(),
1051 augment.getCharPosition(), augment.getFileName()));
Bharat saraswald14cbe82016-07-14 13:26:18 +05301052 }
1053 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301054 throw new LinkerException(getErrorMsg(
1055 FAILED_TO_LINK, augment.getName(), augment
1056 .getLineNumber(), augment.getCharPosition(),
1057 augment.getFileName()));
Bharat saraswald14cbe82016-07-14 13:26:18 +05301058 }
Vidyashree Ramab3670472016-08-06 15:49:56 +05301059 } else if (entityToResolve instanceof YangCompilerAnnotation) {
1060 YangNode targetNode;
1061 YangCompilerAnnotation ca = (YangCompilerAnnotation) entityToResolve;
Bharat saraswal94844d62016-10-13 13:28:03 +05301062 targetNode = xPathLinker.processXpathLinking(ca.getAtomicPathList(),
1063 (YangNode) root,
1064 AUGMENT_LINKING);
Vidyashree Ramab3670472016-08-06 15:49:56 +05301065 if (targetNode != null) {
1066 if (targetNode instanceof YangList) {
1067 ((YangList) targetNode).setCompilerAnnotation(
1068 (YangCompilerAnnotation) entityToResolve);
1069 Resolvable resolvable = (Resolvable) entityToResolve;
1070 resolvable.setResolvableStatus(RESOLVED);
1071 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301072 throw new LinkerException(getErrorMsg(
1073 INVALID_TARGET + targetNode.getNodeType(), ca.getPath(),
1074 ca.getLineNumber(), ca.getCharPosition(), ca.getFileName()));
Vidyashree Ramab3670472016-08-06 15:49:56 +05301075 }
1076 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301077 throw new LinkerException(getErrorMsg(
1078 FAILED_TO_FIND_ANNOTATION, ca.getPath(), ca.getLineNumber(),
1079 ca.getCharPosition(), ca.getFileName()));
Vidyashree Ramab3670472016-08-06 15:49:56 +05301080 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301081 } else if (entityToResolve instanceof YangLeafRef) {
1082 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301083 Object target = xPathLinker.processLeafRefXpathLinking(
Bharat saraswal94844d62016-10-13 13:28:03 +05301084 leafRef.getAtomicPath(), (YangNode) root, leafRef, LEAF_REF_LINKING);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301085 if (target != null) {
Bharat saraswale3175d32016-08-31 17:50:11 +05301086 YangLeaf leaf;
1087 YangLeafList leafList;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301088 leafRef.setReferredLeafOrLeafList(target);
1089 if (target instanceof YangLeaf) {
1090 leaf = (YangLeaf) target;
janani bebb143d2016-07-14 19:35:22 +05301091 leafRef.setResolvableStatus(INTER_FILE_LINKED);
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301092 addUnResolvedLeafRefTypeToStack((T) leaf, entityToResolveInfo
1093 .getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301094 } else {
1095 leafList = (YangLeafList) target;
janani bebb143d2016-07-14 19:35:22 +05301096 leafRef.setResolvableStatus(INTER_FILE_LINKED);
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301097 addUnResolvedLeafRefTypeToStack(
1098 (T) leafList, entityToResolveInfo.getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301099 }
janani b3a3e3262016-10-19 00:23:28 +05301100 fillPathPredicates(leafRef);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301101 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301102 LinkerException ex = new LinkerException(
1103 FAILED_TO_FIND_LEAD_INFO_HOLDER + leafRef.getPath());
1104 ex.setCharPosition(leafRef.getCharPosition());
1105 ex.setLine(leafRef.getLineNumber());
1106 ex.setFileName(leafRef.getFileName());
1107 throw ex;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301108 }
1109 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301110 }
1111
1112 /**
1113 * Returns the referenced prefix of entity under resolution.
1114 *
1115 * @return referenced prefix of entity under resolution
1116 * @throws DataModelException a violation in data model rule
1117 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301118 private String getRefPrefix()
1119 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301120 T entity = getCurEntityToResolveFromStack();
1121 if (entity instanceof YangType) {
1122 return ((YangType<?>) entity).getPrefix();
janani b0e4e8ae2016-07-13 21:06:41 +05301123 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301124 if (entity instanceof YangUses) {
1125 return ((YangUses) entity).getPrefix();
1126 }
1127 if (entity instanceof YangIfFeature) {
1128 return ((YangIfFeature) entity).getPrefix();
1129 }
1130 if (entity instanceof YangBase) {
1131 return ((YangBase) entity).getBaseIdentifier()
1132 .getPrefix();
1133 }
1134 if (entity instanceof YangIdentityRef) {
1135 return ((YangIdentityRef) entity).getPrefix();
1136 }
1137 throw new DataModelException(LINKER_ERROR);
janani b0e4e8ae2016-07-13 21:06:41 +05301138 }
1139
1140 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301141 * Performs inter file linking and resolution.
1142 *
1143 * @throws DataModelException a violation in data model rule
1144 */
1145 private void linkInterFileAndResolve()
1146 throws DataModelException {
1147
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301148 while (!partialResolvedStack.isEmpty()) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301149
1150 // Current node to resolve, it can be a YANG type or YANG uses.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301151 T entityToResolve = getCurEntityToResolveFromStack();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301152 // Check if linking is already done
1153 if (entityToResolve instanceof Resolvable) {
1154
1155 Resolvable resolvable = (Resolvable) entityToResolve;
1156 switch (resolvable.getResolvableStatus()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301157 case RESOLVED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301158 /*
1159 * If the entity is already resolved in the stack, then pop
1160 * it and continue with the remaining stack elements to
1161 * resolve
1162 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301163 partialResolvedStack.pop();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301164 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301165
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301166 case INTER_FILE_LINKED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301167 /*
1168 * If the top of the stack is already linked then resolve
1169 * the references and pop the entity and continue with
1170 * remaining stack elements to resolve
1171 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301172 resolveTopOfStack();
1173 partialResolvedStack.pop();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301174 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301175
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301176 case INTRA_FILE_RESOLVED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301177 /*
1178 * If the top of the stack is intra file resolved then check
1179 * if top of stack is linked, if not link it using
1180 * import/include list and push the linked referred entity
1181 * to the stack, otherwise only push it to the stack.
1182 */
1183 linkInterFileTopOfStackRefUpdateStack();
1184 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301185
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301186 case UNDEFINED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301187 /*
1188 * In case of if-feature resolution, if referred "feature" is not
1189 * defined then the resolvable status will be undefined.
1190 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301191 partialResolvedStack.pop();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301192 break;
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301193
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301194 default:
1195 throw new DataModelException(INVALID_LINKER_STATE);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301196 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301197 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301198 throw new DataModelException(INVALID_RESOLVED_ENTITY);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301199 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301200 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301201 }
1202
1203 /**
1204 * Links the top of the stack if it's inter-file and update stack.
1205 *
1206 * @throws DataModelException data model error
1207 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301208 private void linkInterFileTopOfStackRefUpdateStack()
1209 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301210 T entity = getCurEntityToResolveFromStack();
1211 if (entity instanceof YangLeafRef) {
janani bebb143d2016-07-14 19:35:22 +05301212 // When leafref path comes with relative path, it will be converted to absolute path.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301213 setAbsolutePathFromRelativePathInLeafref(entity);
1214 processXPathLinking(entity, curRefResolver);
janani bebb143d2016-07-14 19:35:22 +05301215 return;
1216 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301217 /*
1218 * Obtain the referred node of top of stack entity under resolution
1219 */
Bharat saraswal94844d62016-10-13 13:28:03 +05301220 T refNode = getRefNode();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301221
1222 /*
1223 * Check for null for scenario when it's not linked and inter-file
1224 * linking is required.
1225 */
Bharat saraswal94844d62016-10-13 13:28:03 +05301226 if (refNode == null) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301227
1228 /*
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301229 * Check if prefix is null or not, to identify whether to search in
1230 * import list or include list.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301231 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301232 if (getRefPrefix() != null && !getRefPrefix()
1233 .contentEquals(curRefResolver.getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301234 if (resolveWithImport()) {
1235 return;
1236 }
1237 } else {
1238 if (resolveWithInclude()) {
1239 return;
1240 }
1241 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301242
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301243 if (entity instanceof YangIfFeature) {
1244 ((YangIfFeature) entity).setResolvableStatus(UNDEFINED);
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301245 return;
1246 }
janani b0e4e8ae2016-07-13 21:06:41 +05301247 // If current entity is still not resolved, then
1248 // linking/resolution has failed.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301249
1250 DataModelException ex = new DataModelException(
1251 getErrorInfoForLinker(entity));
1252 ex.setLine(getLineNumber());
1253 ex.setCharPosition(getCharPosition());
1254 throw ex;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301255 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301256 ((Resolvable) entity).setResolvableStatus(INTER_FILE_LINKED);
Bharat saraswal94844d62016-10-13 13:28:03 +05301257 addUnresolvedRecursiveReferenceToStack((YangNode) refNode);
janani bebb143d2016-07-14 19:35:22 +05301258 }
1259 }
1260
1261 /**
1262 * Sets the leafref with absolute path from the relative path.
1263 *
1264 * @param resolutionInfo information about the YANG construct which has to be resolved
1265 * @throws DataModelException a violation of data model rules
1266 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301267 private void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301268 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301269 if (resolutionInfo instanceof YangLeafRef) {
1270
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301271 YangNode leafParent = ((YangLeafRef) resolutionInfo)
janani b3a3e3262016-10-19 00:23:28 +05301272 .getParentNode();
janani bebb143d2016-07-14 19:35:22 +05301273 YangLeafRef leafref = (YangLeafRef) resolutionInfo;
1274
1275 // Checks if the leafref has relative path in it.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301276 if (leafref.getPathType() == RELATIVE_PATH) {
janani bebb143d2016-07-14 19:35:22 +05301277 YangRelativePath relativePath = leafref.getRelativePath();
1278 List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301279 int ancestorCount = relativePath.getAncestorNodeCount();
janani bebb143d2016-07-14 19:35:22 +05301280
1281 // Gets the root node from the ancestor count.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301282 T nodeOrAugmentList =
1283 getRootNodeWithAncestorCountForLeafref(ancestorCount, leafParent,
1284 leafref);
janani bebb143d2016-07-14 19:35:22 +05301285 if (nodeOrAugmentList instanceof YangNode) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301286 StringBuilder name = new StringBuilder();
1287 StringBuilder prefix = new StringBuilder();
janani bebb143d2016-07-14 19:35:22 +05301288 YangNode rootNode = (YangNode) nodeOrAugmentList;
1289 // Forms a new absolute path from the relative path
1290 while (!(rootNode instanceof YangReferenceResolver)) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301291 name.append(rootNode.getName());
1292 prefix.append(SLASH_FOR_STRING).append(name.reverse());
1293 name.delete(0, name.length());
janani bebb143d2016-07-14 19:35:22 +05301294 rootNode = rootNode.getParent();
1295 if (rootNode == null) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301296 throw new DataModelException(INVALID_TREE);
janani bebb143d2016-07-14 19:35:22 +05301297 }
1298 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301299 prefix.reverse();
1300 fillAbsolutePathValuesInLeafref(leafref, prefix.toString(),
1301 absoluteInRelative);
janani bebb143d2016-07-14 19:35:22 +05301302 } else {
1303 List<String> listOfAugment = (List<String>) nodeOrAugmentList;
1304 Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301305 StringBuilder augment = new StringBuilder(EMPTY_STRING);
janani bebb143d2016-07-14 19:35:22 +05301306 while (listOfAugmentIterator.hasNext()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301307 augment.append(SLASH_FOR_STRING)
1308 .append(listOfAugmentIterator.next());
janani bebb143d2016-07-14 19:35:22 +05301309 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301310 fillAbsolutePathValuesInLeafref(leafref, augment.toString(),
1311 absoluteInRelative);
janani b0e4e8ae2016-07-13 21:06:41 +05301312 }
janani b0e4e8ae2016-07-13 21:06:41 +05301313 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301314 }
1315 }
1316
1317 /**
janani bebb143d2016-07-14 19:35:22 +05301318 * Fills the absolute path values in the leafref from relative path.
1319 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301320 * @param leafref instance of YANG leafref
1321 * @param path path name which has to be prefixed to relative path
1322 * @param relative atomic paths in relative
janani bebb143d2016-07-14 19:35:22 +05301323 * @throws DataModelException a violation of data model rules
1324 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301325 private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String path,
1326 List<YangAtomicPath> relative)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301327 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301328 leafref.setPathType(ABSOLUTE_PATH);
janani bebb143d2016-07-14 19:35:22 +05301329 String[] pathName = new String[0];
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301330 if (path != null && !path.equals(EMPTY_STRING)) {
1331 pathName = path.split(SLASH_FOR_STRING);
janani bebb143d2016-07-14 19:35:22 +05301332 }
1333 List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
1334 for (String value : pathName) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301335 if (value != null && !value.isEmpty() && !value.equals(EMPTY_STRING)) {
1336 YangNodeIdentifier nodeId = getValidNodeIdentifier(value, PATH_DATA);
janani bebb143d2016-07-14 19:35:22 +05301337 YangAtomicPath atomicPath = new YangAtomicPath();
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301338 atomicPath.setNodeIdentifier(nodeId);
janani bebb143d2016-07-14 19:35:22 +05301339 finalListForAbsolute.add(atomicPath);
1340 }
1341 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301342 if (relative != null && !relative.isEmpty()) {
1343 Iterator<YangAtomicPath> pathIt = relative.listIterator();
1344 while (pathIt.hasNext()) {
1345 YangAtomicPath yangAtomicPath = pathIt.next();
janani bebb143d2016-07-14 19:35:22 +05301346 finalListForAbsolute.add(yangAtomicPath);
1347 }
1348 leafref.setAtomicPath(finalListForAbsolute);
1349 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301350 DataModelException ex = new DataModelException(getLeafRefErrorInfo(leafref));
1351 ex.setCharPosition(leafref.getCharPosition());
1352 ex.setLine(leafref.getLineNumber());
1353 ex.setFileName(leafref.getFileName());
1354 throw ex;
janani bebb143d2016-07-14 19:35:22 +05301355 }
1356 }
1357
1358 /**
1359 * Returns the root parent with respect to the ancestor count from leafref.
1360 *
1361 * @param ancestorCount count of node where parent node can be reached
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301362 * @param curParent current parent node
janani bebb143d2016-07-14 19:35:22 +05301363 * @param leafref instance of YANG leafref
1364 * @return node where the ancestor count stops or augment path name list
1365 * @throws DataModelException a violation of data model rules
1366 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301367 private T getRootNodeWithAncestorCountForLeafref(
1368 int ancestorCount, YangNode curParent, YangLeafRef leafref)
janani bebb143d2016-07-14 19:35:22 +05301369 throws DataModelException {
1370
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301371 int curParentCount = 1;
1372 curParent = skipInvalidDataNodes(curParent, leafref);
1373 if (curParent instanceof YangAugment) {
1374 YangAugment augment = (YangAugment) curParent;
1375 List<String> valueInAugment = getPathWithAugment(augment,
1376 ancestorCount - curParentCount);
janani bebb143d2016-07-14 19:35:22 +05301377 return (T) valueInAugment;
1378 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301379 while (curParentCount < ancestorCount) {
1380 YangNode currentSkippedParent = skipInvalidDataNodes(curParent, leafref);
1381 if (currentSkippedParent == curParent) {
1382 if (curParent.getParent() == null) {
1383 throw new DataModelException(getLeafRefErrorInfo(leafref));
janani bebb143d2016-07-14 19:35:22 +05301384 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301385 curParent = curParent.getParent();
janani bebb143d2016-07-14 19:35:22 +05301386 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301387 curParent = currentSkippedParent;
janani bebb143d2016-07-14 19:35:22 +05301388 continue;
1389 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301390 curParentCount = curParentCount + 1;
1391 if (curParent instanceof YangAugment) {
1392 YangAugment augment = (YangAugment) curParent;
1393 List<String> valueInAugment = getPathWithAugment(
1394 augment, ancestorCount - curParentCount);
janani bebb143d2016-07-14 19:35:22 +05301395 return (T) valueInAugment;
1396 }
1397 }
1398 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301399 return (T) curParent;
janani bebb143d2016-07-14 19:35:22 +05301400 }
1401
1402 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301403 * Finds and resolves with include list.
1404 *
1405 * @return true if resolved, false otherwise
1406 * @throws DataModelException a violation in data model rule
1407 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301408 private boolean resolveWithInclude() throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301409 /*
1410 * Run through all the nodes in include list and search for referred
1411 * typedef/grouping at the root level.
1412 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301413 for (YangInclude yangInclude : curRefResolver.getIncludeList()) {
1414 YangNode linkedNode = getLinkedNode(yangInclude.getIncludedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301415 if (linkedNode != null) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301416 return addUnResolvedRefToStack(linkedNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301417 }
1418 }
1419 // If referred node can't be found return false.
1420 return false;
1421 }
1422
1423 /**
1424 * Finds and resolves with import list.
1425 *
1426 * @return true if resolved, false otherwise
1427 * @throws DataModelException a violation in data model rule
1428 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301429 private boolean resolveWithImport() throws DataModelException {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301430
1431 // Run through import list to find the referred typedef/grouping.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301432 for (YangImport yangImport : curRefResolver.getImportList()) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301433 /*
1434 * Match the prefix attached to entity under resolution with the
1435 * imported/included module/sub-module's prefix. If found, search
1436 * for the referred typedef/grouping at the root level.
1437 */
1438 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301439 YangNode linkedNode = getLinkedNode(yangImport.getImportedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301440 if (linkedNode != null) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301441 return addUnResolvedRefToStack(linkedNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301442 }
1443 /*
1444 * If referred node can't be found at root level break for loop,
1445 * and return false.
1446 */
1447 break;
1448 }
1449 }
1450 // If referred node can't be found return false.
1451 return false;
1452 }
1453
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301454 //Add unresolved constructs to stack.
1455 private boolean addUnResolvedRefToStack(YangNode linkedNode)
1456 throws DataModelException {
1457 // Add the link to external entity.
1458 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
1459
1460 // Add the type/uses of referred typedef/grouping to the stack.
1461 addUnresolvedRecursiveReferenceToStack(linkedNode);
1462 return true;
1463 }
1464
1465 //Returns linked node from entity of stack.
1466 private YangNode getLinkedNode(YangNode node) {
1467 T entity = getCurEntityToResolveFromStack();
1468 if (entity instanceof YangType) {
1469 return findRefTypedef(node);
1470 }
1471 if (entity instanceof YangUses) {
1472 return findRefGrouping(node);
1473 }
1474 if (entity instanceof YangIfFeature) {
1475 return findRefFeature(node);
1476 }
1477 if (entity instanceof YangBase) {
1478 return findRefIdentity(node);
1479 }
1480 if (entity instanceof YangIdentityRef) {
1481 return findRefIdentityRef(node);
1482 }
1483 return null;
1484 }
1485
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301486 /**
1487 * Returns referred typedef/grouping node.
1488 *
1489 * @return referred typedef/grouping node
1490 * @throws DataModelException a violation in data model rule
1491 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301492 private T getRefNode() throws DataModelException {
1493 T entity = getCurEntityToResolveFromStack();
1494 if (entity instanceof YangType) {
1495 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>)
1496 ((YangType<?>) entity).getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301497 return (T) derivedInfo.getReferredTypeDef();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301498 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301499 if (entity instanceof YangUses) {
1500 return (T) ((YangUses) entity).getRefGroup();
1501 }
1502 if (entity instanceof YangIfFeature) {
1503 return (T) ((YangIfFeature) entity).getReferredFeatureHolder();
1504 }
1505 if (entity instanceof YangLeafRef) {
1506 return (T) ((YangLeafRef) entity).getReferredLeafOrLeafList();
1507 }
1508 if (entity instanceof YangBase) {
1509 return (T) ((YangBase) entity).getReferredIdentity();
1510 }
1511 if (entity instanceof YangIdentityRef) {
1512 return (T) ((YangIdentityRef) entity).getReferredIdentity();
1513 }
1514 throw new DataModelException(LINKER_ERROR);
1515
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301516 }
1517
1518 /**
1519 * Finds the referred grouping node at the root level of imported/included node.
1520 *
1521 * @param refNode module/sub-module node
1522 * @return referred grouping
1523 */
1524 private YangNode findRefGrouping(YangNode refNode) {
1525 YangNode tmpNode = refNode.getChild();
1526 while (tmpNode != null) {
1527 if (tmpNode instanceof YangGrouping) {
1528 if (tmpNode.getName()
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301529 .equals(((YangUses) getCurEntityToResolveFromStack())
1530 .getName())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301531 return tmpNode;
1532 }
1533 }
1534 tmpNode = tmpNode.getNextSibling();
1535 }
1536 return null;
1537 }
1538
1539 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301540 * Finds the referred feature node at the root level of imported/included node.
1541 *
1542 * @param refNode module/sub-module node
1543 * @return referred feature
1544 */
1545 private YangNode findRefFeature(YangNode refNode) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301546 T entity = getCurEntityToResolveFromStack();
1547 YangNodeIdentifier ifFeature = ((YangIfFeature) entity).getName();
1548 List<YangFeature> featureList = ((YangFeatureHolder) refNode)
1549 .getFeatureList();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301550 if (featureList != null && !featureList.isEmpty()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301551 for (YangFeature feature : featureList) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301552 if (ifFeature.getName().equals(feature.getName())) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301553 ((YangIfFeature) entity).setReferredFeature(feature);
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301554 return refNode;
1555 }
1556 }
1557 }
1558 return null;
1559 }
1560
1561 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301562 * Finds the referred typedef node at the root level of imported/included node.
1563 *
1564 * @param refNode module/sub-module node
1565 * @return referred typedef
1566 */
1567 private YangNode findRefTypedef(YangNode refNode) {
1568 YangNode tmpNode = refNode.getChild();
1569 while (tmpNode != null) {
1570 if (tmpNode instanceof YangTypeDef) {
1571 if (tmpNode.getName()
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301572 .equals(((YangType) getCurEntityToResolveFromStack())
1573 .getDataTypeName())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301574 return tmpNode;
1575 }
1576 }
1577 tmpNode = tmpNode.getNextSibling();
1578 }
1579 return null;
1580 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301581
1582 /**
1583 * Finds the referred identity node at the root level of imported/included node.
1584 *
1585 * @param refNode module/sub-module node
1586 * @return referred identity
1587 */
1588 private YangNode findRefIdentity(YangNode refNode) {
1589 YangNode tmpNode = refNode.getChild();
1590 while (tmpNode != null) {
1591 if (tmpNode instanceof YangIdentity) {
1592 if (tmpNode.getName()
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301593 .equals(((YangBase) getCurEntityToResolveFromStack())
1594 .getBaseIdentifier().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301595 return tmpNode;
1596 }
1597 }
1598 tmpNode = tmpNode.getNextSibling();
1599 }
1600 return null;
1601 }
1602
1603 /**
1604 * Finds the referred identity node at the root level of imported/included node.
1605 *
1606 * @param refNode module/sub-module node
1607 * @return referred identity
1608 */
1609 private YangNode findRefIdentityRef(YangNode refNode) {
1610 YangNode tmpNode = refNode.getChild();
1611 while (tmpNode != null) {
1612 if (tmpNode instanceof YangIdentity) {
1613 if (tmpNode.getName()
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301614 .equals(((YangIdentityRef) getCurEntityToResolveFromStack())
1615 .getBaseIdentity().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301616 return tmpNode;
1617 }
1618 }
1619 tmpNode = tmpNode.getNextSibling();
1620 }
1621 return null;
1622 }
Bharat saraswal2da23bf2016-08-25 15:28:39 +05301623
Vidyashree Ramab20ba9e2016-09-02 14:12:25 +05301624 /**
1625 * Sets descendant node augmented flag in ancestors.
1626 *
1627 * @param targetNode augmented YANG node
1628 */
1629 private void setAugmentedFlagInAncestors(YangNode targetNode) {
1630 targetNode = targetNode.getParent();
1631 while (targetNode != null) {
1632 targetNode.setDescendantNodeAugmented(true);
1633 targetNode = targetNode.getParent();
1634 }
1635 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301636}