blob: 7c9780577e778892486c213a8ec8d02283a17850 [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;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053021import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
Vidyashree Rama72719fa2016-07-15 14:06:56 +053022import org.onosproject.yangutils.datamodel.TraversalType;
janani b0e4e8ae2016-07-13 21:06:41 +053023import org.onosproject.yangutils.datamodel.YangAtomicPath;
Bharat saraswald14cbe82016-07-14 13:26:18 +053024import org.onosproject.yangutils.datamodel.YangAugment;
25import org.onosproject.yangutils.datamodel.YangAugmentableNode;
Shankara-Huawei234cd092016-07-14 11:35:34 +053026import org.onosproject.yangutils.datamodel.YangBase;
Vidyashree Ramab3670472016-08-06 15:49:56 +053027import org.onosproject.yangutils.datamodel.YangCompilerAnnotation;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053028import org.onosproject.yangutils.datamodel.YangDerivedInfo;
janani bebb143d2016-07-14 19:35:22 +053029import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053030import org.onosproject.yangutils.datamodel.YangFeature;
31import org.onosproject.yangutils.datamodel.YangFeatureHolder;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053032import org.onosproject.yangutils.datamodel.YangGrouping;
Shankara-Huawei234cd092016-07-14 11:35:34 +053033import org.onosproject.yangutils.datamodel.YangIdentity;
34import org.onosproject.yangutils.datamodel.YangIdentityRef;
Bharat saraswalaf413b82016-07-14 15:18:20 +053035import org.onosproject.yangutils.datamodel.YangIfFeature;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053036import org.onosproject.yangutils.datamodel.YangImport;
37import org.onosproject.yangutils.datamodel.YangInclude;
janani b0e4e8ae2016-07-13 21:06:41 +053038import org.onosproject.yangutils.datamodel.YangInput;
39import org.onosproject.yangutils.datamodel.YangLeaf;
40import org.onosproject.yangutils.datamodel.YangLeafList;
41import org.onosproject.yangutils.datamodel.YangLeafRef;
Vidyashree Ramab3670472016-08-06 15:49:56 +053042import org.onosproject.yangutils.datamodel.YangList;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053043import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053044import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053045import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani b0e4e8ae2016-07-13 21:06:41 +053046import org.onosproject.yangutils.datamodel.YangRelativePath;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053047import org.onosproject.yangutils.datamodel.YangResolutionInfo;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053048import org.onosproject.yangutils.datamodel.YangType;
49import org.onosproject.yangutils.datamodel.YangTypeDef;
50import org.onosproject.yangutils.datamodel.YangUses;
Bharat saraswald14cbe82016-07-14 13:26:18 +053051import org.onosproject.yangutils.datamodel.YangXPathResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053052import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053053import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
janani b0e4e8ae2016-07-13 21:06:41 +053054import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
Bharat saraswald14cbe82016-07-14 13:26:18 +053055import org.onosproject.yangutils.linker.exceptions.LinkerException;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053056
Bharat saraswal9fab16b2016-09-23 23:27:24 +053057import java.io.Serializable;
58import java.util.Iterator;
59import java.util.LinkedList;
60import java.util.List;
61import java.util.Stack;
62
Bharat saraswal9fab16b2016-09-23 23:27:24 +053063import static org.onosproject.yangutils.datamodel.ResolvableType.YANG_LEAFREF;
Vidyashree Rama72719fa2016-07-15 14:06:56 +053064import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
65import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
66import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
67import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053068import static org.onosproject.yangutils.datamodel.YangPathArgType.ABSOLUTE_PATH;
69import static org.onosproject.yangutils.datamodel.YangPathArgType.RELATIVE_PATH;
70import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.getErrorMsg;
janani bebb143d2016-07-14 19:35:22 +053071import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053072import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
73import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
74import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
75import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053076import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNDEFINED;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053077import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053078import static org.onosproject.yangutils.datamodel.utils.YangConstructType.PATH_DATA;
Bharat saraswal94844d62016-10-13 13:28:03 +053079import static org.onosproject.yangutils.linker.impl.XpathLinkingTypes.AUGMENT_LINKING;
80import static org.onosproject.yangutils.linker.impl.XpathLinkingTypes.LEAF_REF_LINKING;
Bharat saraswald14cbe82016-07-14 13:26:18 +053081import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
janani b3a3e3262016-10-19 00:23:28 +053082import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.fillPathPredicates;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053083import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getErrorInfoForLinker;
84import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getLeafRefErrorInfo;
janani bebb143d2016-07-14 19:35:22 +053085import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
86import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getValidNodeIdentifier;
87import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.skipInvalidDataNodes;
janani bebb143d2016-07-14 19:35:22 +053088import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053089import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_FIND_ANNOTATION;
90import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_FIND_LEAD_INFO_HOLDER;
91import static org.onosproject.yangutils.utils.UtilConstants.FAILED_TO_LINK;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053092import static org.onosproject.yangutils.utils.UtilConstants.INVALID_ENTITY;
93import static org.onosproject.yangutils.utils.UtilConstants.INVALID_LINKER_STATE;
94import static org.onosproject.yangutils.utils.UtilConstants.INVALID_RESOLVED_ENTITY;
95import static org.onosproject.yangutils.utils.UtilConstants.INVALID_TARGET;
96import static org.onosproject.yangutils.utils.UtilConstants.INVALID_TREE;
janani b0e4e8ae2016-07-13 21:06:41 +053097import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
Bharat saraswal9fab16b2016-09-23 23:27:24 +053098import static org.onosproject.yangutils.utils.UtilConstants.LINKER_ERROR;
janani bebb143d2016-07-14 19:35:22 +053099import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530100import static org.onosproject.yangutils.utils.UtilConstants.UNRESOLVABLE;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530101
102/**
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530103 * Represents implementation of resolution object which will be resolved by
104 * linker.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530105 *
106 * @param <T> type of resolution entity uses / type
107 */
Bharat saraswale3175d32016-08-31 17:50:11 +0530108public class YangResolutionInfoImpl<T> extends DefaultLocationInfo
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530109 implements YangResolutionInfo<T>, Serializable {
110
111 private static final long serialVersionUID = 806201658L;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530112
113 /**
114 * Information about the entity that needs to be resolved.
115 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530116 private YangEntityToResolveInfoImpl<T> entityToResolveInfo;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530117
118 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530119 * Current module/sub-module reference, will be used in inter-file/
120 * inter-jar scenario to get the import/include list.
121 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530122 private YangReferenceResolver curRefResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530123
124 /**
125 * Stack for type/uses is maintained for hierarchical references, this is
126 * used during resolution.
127 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530128 private Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530129
130 /**
131 * It is private to ensure the overloaded method be invoked to create an
132 * object.
133 */
134 @SuppressWarnings("unused")
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530135 private YangResolutionInfoImpl() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530136 }
137
138 /**
139 * Creates a resolution information object with all the inputs.
140 *
141 * @param dataNode current parsable data node
142 * @param holderNode parent YANG node
143 * @param lineNumber error line number
144 * @param charPositionInLine error character position in line
145 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530146 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber,
147 int charPositionInLine) {
148 entityToResolveInfo = new YangEntityToResolveInfoImpl<>();
149 entityToResolveInfo.setEntityToResolve(dataNode);
150 entityToResolveInfo.setHolderOfEntityToResolve(holderNode);
151 setLineNumber(lineNumber);
152 setCharPosition(charPositionInLine);
153 partialResolvedStack = new Stack<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530154 }
155
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530156 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530157 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
158 throws DataModelException {
159
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530160 curRefResolver = dataModelRootNode;
161 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530162 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
163 * YANG leafref or YANG base or YANG identityref.
164 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530165 T entityToResolve = entityToResolveInfo.getEntityToResolve();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530166
167 // Check if linking is already done
168 if (entityToResolve instanceof Resolvable) {
169 Resolvable resolvable = (Resolvable) entityToResolve;
170 if (resolvable.getResolvableStatus() == RESOLVED) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530171 /*
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530172 * entity is already resolved, so nothing to do
173 */
174 return;
175 }
176 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530177 throw new DataModelException(LINKER_ERROR);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530178 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530179 // Push the initial entity to resolve in stack.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530180 addInPartialResolvedStack(entityToResolveInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530181 linkAndResolvePartialResolvedStack();
janani b0e4e8ae2016-07-13 21:06:41 +0530182 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530183 }
184
185 /**
186 * Resolves linking with ancestors.
187 *
188 * @throws DataModelException a violation of data model rules
189 */
190 private void linkAndResolvePartialResolvedStack()
191 throws DataModelException {
192
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530193 while (!partialResolvedStack.isEmpty()) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530194 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530195 * Current node to resolve, it can be a YANG type or YANG uses or
196 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
197 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530198 T entityToResolve = getCurEntityToResolveFromStack();
199 if (!(entityToResolve instanceof Resolvable)) {
200 throw new DataModelException(LINKER_ERROR);
201 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530202 // Check if linking is already done
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530203 Resolvable resolvable = (Resolvable) entityToResolve;
204 switch (resolvable.getResolvableStatus()) {
205 case RESOLVED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530206 /*
207 * If the entity is already resolved in the stack, then pop
208 * it and continue with the remaining stack elements to
209 * resolve
210 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530211 partialResolvedStack.pop();
212 break;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530213
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530214 case LINKED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530215 /*
216 * If the top of the stack is already linked then resolve
217 * the references and pop the entity and continue with
218 * remaining stack elements to resolve.
219 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530220 resolveTopOfStack();
221 partialResolvedStack.pop();
222 break;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530223
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530224 case INTRA_FILE_RESOLVED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530225 /*
226 * Pop the top of the stack.
227 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530228 partialResolvedStack.pop();
229 break;
230
231 case UNRESOLVED:
232 linkTopOfStackReferenceUpdateStack();
233
234 if (resolvable.getResolvableStatus() == UNRESOLVED) {
235 // If current entity is still not resolved, then
236 // linking/resolution has failed.
237 DataModelException ex =
238 new DataModelException
239 (getErrorInfoForLinker(resolvable));
240 ex.setLine(getLineNumber());
241 ex.setCharPosition(getCharPosition());
242 throw ex;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530243 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530244 break;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530245
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530246 default:
247 throw new DataModelException(INVALID_LINKER_STATE);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530248 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530249 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530250 }
251
252 /**
janani bc27947a2016-10-19 01:17:40 +0530253 * Adds leaf-ref to the resolution list, with different context if
254 * leaf-ref is defined under derived type. Leaf-ref must be resolved from
255 * where the typedef is referenced.
janani b0e4e8ae2016-07-13 21:06:41 +0530256 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530257 private void addDerivedRefTypeToRefTypeResolutionList()
258 throws DataModelException {
janani b0e4e8ae2016-07-13 21:06:41 +0530259
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530260 YangNode refNode = entityToResolveInfo.getHolderOfEntityToResolve();
janani bc27947a2016-10-19 01:17:40 +0530261 YangDerivedInfo info = getValidResolvableType();
janani b0e4e8ae2016-07-13 21:06:41 +0530262
janani bc27947a2016-10-19 01:17:40 +0530263 if (info == null) {
janani b0e4e8ae2016-07-13 21:06:41 +0530264 return;
265 }
266
janani bc27947a2016-10-19 01:17:40 +0530267 YangType<T> type =
268 (YangType<T>) entityToResolveInfo.getEntityToResolve();
269
270 T extType = (T) info.getReferredTypeDef().getTypeDefBaseType()
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530271 .getDataTypeExtendedInfo();
janani b0e4e8ae2016-07-13 21:06:41 +0530272
janani bc27947a2016-10-19 01:17:40 +0530273 while (extType instanceof YangDerivedInfo) {
274 info = (YangDerivedInfo) extType;
275 extType = (T) info.getReferredTypeDef().getTypeDefBaseType()
276 .getDataTypeExtendedInfo();
janani b0e4e8ae2016-07-13 21:06:41 +0530277 }
janani b0e4e8ae2016-07-13 21:06:41 +0530278 /*
janani bc27947a2016-10-19 01:17:40 +0530279 * Backup the leaf-ref info from derived type and deletes the derived
280 * type info. Copies the backed up leaf-ref data to the actual type in
281 * replacement of derived type. Adds to the resolution list in this
282 * context.
janani b0e4e8ae2016-07-13 21:06:41 +0530283 */
janani bc27947a2016-10-19 01:17:40 +0530284 addRefTypeInfo(extType, type, refNode);
janani b0e4e8ae2016-07-13 21:06:41 +0530285 }
286
janani bc27947a2016-10-19 01:17:40 +0530287 /**
288 * Returns the derived info if the holder is typedef, the entity is type
289 * and the effective type is leaf-ref; null otherwise.
290 *
291 * @return derived info
292 */
293 private YangDerivedInfo<?> getValidResolvableType() {
294
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530295 YangNode refNode = entityToResolveInfo.getHolderOfEntityToResolve();
296 T entity = entityToResolveInfo.getEntityToResolve();
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530297
janani bc27947a2016-10-19 01:17:40 +0530298 if (!(refNode instanceof YangTypeDef) && entity instanceof YangType) {
299 YangType<?> type = (YangType) entity;
300 YangDerivedInfo<?> info =
301 (YangDerivedInfo) type.getDataTypeExtendedInfo();
302 YangDataTypes dataType = info.getEffectiveBuiltInType();
303 if ((type.getResolvableStatus() == RESOLVED) &&
304 (dataType == YangDataTypes.LEAFREF)) {
305 return info;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530306 }
307 }
308 return null;
309 }
310
311 /**
janani bc27947a2016-10-19 01:17:40 +0530312 * Adds resolvable type (leaf-ref) info to resolution list.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530313 *
janani bc27947a2016-10-19 01:17:40 +0530314 * @param extType resolvable type
315 * @param type YANG type
316 * @param holder holder node
317 * @throws DataModelException if there is a data model error
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530318 */
janani bc27947a2016-10-19 01:17:40 +0530319 private void addRefTypeInfo(T extType, YangType<T> type, YangNode holder)
320 throws DataModelException {
321
322 type.resetYangType();
323 type.setResolvableStatus(RESOLVED);
324 type.setDataType(YangDataTypes.LEAFREF);
325 type.setDataTypeName(LEAFREF);
326 type.setDataTypeExtendedInfo(extType);
327
328 YangLeafRef leafRef = (YangLeafRef) extType;
329 (leafRef).setResolvableStatus(UNRESOLVED);
330 leafRef.setParentNode(holder);
331
332 YangResolutionInfoImpl info = new YangResolutionInfoImpl<>(
333 leafRef, holder, getLineNumber(), getCharPosition());
334 curRefResolver.addToResolutionList(info, YANG_LEAFREF);
335 curRefResolver.resolveSelfFileLinking(YANG_LEAFREF);
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530336 }
337
janani b0e4e8ae2016-07-13 21:06:41 +0530338 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530339 * Resolves the current entity in the stack.
340 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530341 private void resolveTopOfStack()
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530342 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530343 T entity = getCurEntityToResolveFromStack();
344 List<T> entityToResolve = (List<T>) ((Resolvable) entity).resolve();
janani bebb143d2016-07-14 19:35:22 +0530345 if (entityToResolve != null && !entityToResolve.isEmpty()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530346 for (T anEntityToResolve : entityToResolve) {
347 addUnresolvedEntitiesToResolutionList(anEntityToResolve);
janani bebb143d2016-07-14 19:35:22 +0530348 }
349 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530350 if (((Resolvable) entity).getResolvableStatus() != INTRA_FILE_RESOLVED &&
351 ((Resolvable) entity).getResolvableStatus() != UNDEFINED) {
janani b0e4e8ae2016-07-13 21:06:41 +0530352 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530353 ((Resolvable) entity).setResolvableStatus(RESOLVED);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530354 }
355 }
356
357 /**
janani bebb143d2016-07-14 19:35:22 +0530358 * Adds the unresolved entities to the resolution list.
359 *
360 * @param entityToResolve entity to resolve
361 * @throws DataModelException a violation of data model rules
362 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530363 private void addUnresolvedEntitiesToResolutionList(T entityToResolve)
364 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530365 if (entityToResolve instanceof YangEntityToResolveInfoImpl) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530366 YangEntityToResolveInfoImpl entityToResolveInfo
367 = (YangEntityToResolveInfoImpl) entityToResolve;
janani bebb143d2016-07-14 19:35:22 +0530368 if (entityToResolveInfo.getEntityToResolve() instanceof YangLeafRef) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530369 YangLeafRef leafref = (YangLeafRef) entityToResolveInfo
370 .getEntityToResolve();
371 YangNode parentNodeOfLeafref = entityToResolveInfo
372 .getHolderOfEntityToResolve();
janani b3a3e3262016-10-19 00:23:28 +0530373 leafref.setParentNode(parentNodeOfLeafref);
janani bebb143d2016-07-14 19:35:22 +0530374 if (leafref.getResolvableStatus() == UNRESOLVED) {
375 leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
376 }
janani bebb143d2016-07-14 19:35:22 +0530377 }
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530378
379 // Add resolution information to the list.
380 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530381 entityToResolveInfo.getEntityToResolve(),
382 entityToResolveInfo.getHolderOfEntityToResolve(),
383 entityToResolveInfo.getLineNumber(),
384 entityToResolveInfo.getCharPosition());
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530385 addResolutionInfo(resolutionInfoImpl);
janani bebb143d2016-07-14 19:35:22 +0530386 }
387 }
388
389 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530390 * Resolves linking for a node child and siblings.
391 *
392 * @throws DataModelException data model error
393 */
394 private void linkTopOfStackReferenceUpdateStack()
395 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530396 T entity = getCurEntityToResolveFromStack();
397 if (entity instanceof YangLeafRef) {
398 ((Resolvable) entity).setResolvableStatus(INTRA_FILE_RESOLVED);
janani bebb143d2016-07-14 19:35:22 +0530399 return;
400 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530401 /*
402 * Check if self file reference is there, this will not check for the
403 * scenario when prefix is not present and type/uses is present in
404 * sub-module from include list.
405 */
406 if (!isCandidateForSelfFileReference()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530407 ((Resolvable) entity).setResolvableStatus(INTRA_FILE_RESOLVED);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530408 return;
409 }
410
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530411 /*
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530412 * Try to resolve the top of the stack and update partial resolved stack
413 * if there is recursive references
414 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530415 YangNode ancestorRefNode = partialResolvedStack.peek()
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530416 .getHolderOfEntityToResolve();
417
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530418 if (entity instanceof YangIfFeature) {
419 resolveSelfFileLinkingForIfFeature(ancestorRefNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530420 return;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530421 }
422 if (entity instanceof YangIdentityRef || entity instanceof YangBase) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530423 resolveSelfFileLinkingForBaseAndIdentityref();
424 return;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530425 }
426 YangType type = null;
427 if (entity instanceof YangType) {
428 type = (YangType) entity;
429 }
430 /*
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530431 * Traverse up in the ancestor tree to check if the referred node is
432 * defined
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530433 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530434 while (ancestorRefNode != null) {
435 /*
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530436 * Check for the referred node defined in a ancestor scope
437 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530438 YangNode curRefNode = ancestorRefNode.getChild();
439 if (isReferredNodeInSiblingListProcessed(curRefNode)) {
440 return;
441 }
442 ancestorRefNode = ancestorRefNode.getParent();
443 if (type != null && ancestorRefNode != null) {
444 if (ancestorRefNode.getParent() == null) {
445 type.setTypeNotResolvedTillRootNode(true);
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530446 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530447 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530448 }
449
450 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530451 * 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 +0530452 * resolution via include list.
453 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530454 if (getRefPrefix() == null ||
455 getRefPrefix().contentEquals(curRefResolver.getPrefix())) {
456 ((Resolvable) entity).setResolvableStatus(INTRA_FILE_RESOLVED);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530457 }
458 }
459
460 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530461 * Resolves self file linking for base/identityref.
462 *
463 * @throws DataModelException a violation of data model rules
464 */
465 private void resolveSelfFileLinkingForBaseAndIdentityref()
466 throws DataModelException {
467
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530468 boolean refIdentity = false;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530469 String nodeName = null;
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530470 T entity = getCurEntityToResolveFromStack();
471 if (entity instanceof YangIdentityRef) {
472 nodeName = ((YangIdentityRef) entity).getName();
473 } else if (entity instanceof YangBase) {
474 nodeName = ((YangBase) entity).getBaseIdentifier().getName();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530475 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530476 if (curRefResolver instanceof RpcNotificationContainer) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530477 // Sends list of nodes for finding the target identity.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530478 refIdentity = isIdentityReferenceFound(nodeName, (YangNode) curRefResolver);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530479 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530480 if (refIdentity) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530481 return;
482 }
483
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530484 /*
485 * In case prefix is not present or it's self prefix it's a candidate for inter-file
486 * resolution via include list.
487 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530488 if (getRefPrefix() == null || getRefPrefix()
489 .contentEquals(curRefResolver.getPrefix())) {
490 ((Resolvable) entity).setResolvableStatus(INTRA_FILE_RESOLVED);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530491 }
492 }
493
494 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530495 * Resolves self file linking for if-feature.
496 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530497 * @param ancestorRefNode if-feature holder node
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530498 * @throws DataModelException DataModelException a violation of data model
499 * rules
500 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530501 private void resolveSelfFileLinkingForIfFeature(YangNode ancestorRefNode)
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530502 throws DataModelException {
503
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530504 YangFeatureHolder featureHolder = getFeatureHolder(ancestorRefNode);
505 YangNode curRefNode = (YangNode) featureHolder;
506 if (isReferredNode(curRefNode)) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530507
508 // Adds reference link of entity to the node under resolution.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530509 addReferredEntityLink(curRefNode, LINKED);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530510
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530511 /*
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530512 * resolve the reference and update the partial resolution stack
513 * with any further recursive references
514 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530515 addUnresolvedRecursiveReferenceToStack(curRefNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530516 return;
517 }
518
519 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530520 * 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 +0530521 * resolution via include list.
522 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530523 if (getRefPrefix() == null || getRefPrefix()
524 .contentEquals(curRefResolver.getPrefix())) {
525 ((Resolvable) getCurEntityToResolveFromStack())
526 .setResolvableStatus(INTRA_FILE_RESOLVED);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530527 }
528 }
529
janani b0e4e8ae2016-07-13 21:06:41 +0530530 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530531 * Returns the status of the referred identity found for base/identityref.
532 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530533 * @param nodeName the name of the base node
534 * identifier/identityref node identifier
535 * @param ancestorRefNode the parent node of base/identityref
Shankara-Huawei234cd092016-07-14 11:35:34 +0530536 * @return status of referred base/identityref
537 * @throws DataModelException a violation of data model rules
538 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530539 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorRefNode)
Shankara-Huawei234cd092016-07-14 11:35:34 +0530540 throws DataModelException {
541
542 // When child is not present return.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530543 if (ancestorRefNode.getChild() == null) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530544 return false;
545 }
546
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530547 ancestorRefNode = ancestorRefNode.getChild();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530548
549 // Checks all the siblings under the node and returns the matched node.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530550 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorRefNode,
551 nodeName);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530552
553 if (nodeFound != null) {
554 // Adds reference link of entity to the node under resolution.
555 addReferredEntityLink(nodeFound, LINKED);
556
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530557 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530558 * resolve the reference and update the partial resolution stack with any further recursive references
559 */
560 addUnresolvedRecursiveReferenceToStack(nodeFound);
561 return true;
562 }
563
564 return false;
565 }
566
567 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530568 * Adds the unresolved constructs to stack which has to be resolved for leafref.
569 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530570 * @param leavesInfo YANG leaf or leaf list which holds the type
571 * @param ancestorRefNode holder of the YANG leaf or leaf list
janani b0e4e8ae2016-07-13 21:06:41 +0530572 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530573 private void addUnResolvedLeafRefTypeToStack(T leavesInfo, YangNode ancestorRefNode) {
janani b0e4e8ae2016-07-13 21:06:41 +0530574
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530575 YangType refType;
576 T extendedInfo;
577 if (leavesInfo instanceof YangLeaf) {
578 YangLeaf leaf = (YangLeaf) leavesInfo;
579 refType = leaf.getDataType();
janani b0e4e8ae2016-07-13 21:06:41 +0530580 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530581 YangLeafList leafList = (YangLeafList) leavesInfo;
582 refType = leafList.getDataType();
583 }
584 extendedInfo = (T) refType.getDataTypeExtendedInfo();
585 addUnResolvedTypeDataToStack(refType, ancestorRefNode, extendedInfo);
586 }
587
588 //Adds unresolved type info to stack.
589 private void addUnResolvedTypeDataToStack(YangType refType, YangNode
590 ancestorRefNode, T extendedInfo) {
591 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedLeafRef =
592 new YangEntityToResolveInfoImpl<>();
593 YangEntityToResolveInfoImpl<YangType<?>> unResolvedTypeDef =
594 new YangEntityToResolveInfoImpl<>();
595 if (refType.getDataType() == YangDataTypes.LEAFREF) {
596 unResolvedLeafRef.setEntityToResolve((YangLeafRef<?>) extendedInfo);
597 unResolvedLeafRef.setHolderOfEntityToResolve(ancestorRefNode);
598 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedLeafRef);
599 } else if (refType.getDataType() == YangDataTypes.DERIVED) {
600 unResolvedTypeDef.setEntityToResolve(refType);
601 unResolvedTypeDef.setHolderOfEntityToResolve(ancestorRefNode);
602 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedTypeDef);
janani b0e4e8ae2016-07-13 21:06:41 +0530603 }
604 }
605
606 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530607 * Returns feature holder(module/sub-module node) .
608 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530609 * @param ancestorRefNode if-feature holder node
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530610 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530611 private YangFeatureHolder getFeatureHolder(YangNode ancestorRefNode) {
612 while (ancestorRefNode != null) {
613 if (ancestorRefNode instanceof YangFeatureHolder) {
614 return (YangFeatureHolder) ancestorRefNode;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530615 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530616 ancestorRefNode = ancestorRefNode.getParent();
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530617 }
618 return null;
619 }
620
621 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530622 * Checks if the reference in self file or in external file.
623 *
624 * @return true if self file reference, false otherwise
625 * @throws DataModelException a violation of data model rules
626 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530627 private boolean isCandidateForSelfFileReference()
628 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530629 String prefix = getRefPrefix();
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530630 return prefix == null || prefix.contentEquals(curRefResolver.getPrefix());
janani b0e4e8ae2016-07-13 21:06:41 +0530631 }
632
633 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530634 * Checks for the referred parent node for the base/identity.
635 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530636 * @param refNode potential referred node
637 * @return the referred parent node of base/identity.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530638 * @throws DataModelException data model errors
639 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530640 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode refNode,
641 String refName)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530642 throws DataModelException {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530643
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530644 while (refNode != null) {
645 if (refNode instanceof YangIdentity) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530646 // Check if the potential referred node is the actual referred node
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530647 if (isReferredNodeForIdentity(refNode, refName)) {
648 return refNode;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530649 }
650 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530651 refNode = refNode.getNextSibling();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530652 }
653 return null;
654 }
655
656 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530657 * Checks if the current reference node name and the name in the base/identityref base are equal.
658 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530659 * @param curRefNode the node where the reference is pointed
660 * @param name name of the base in the base/identityref base
Shankara-Huawei234cd092016-07-14 11:35:34 +0530661 * @return status of the match between the name
662 * @throws DataModelException a violation of data model rules
663 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530664 private boolean isReferredNodeForIdentity(YangNode curRefNode, String name)
Shankara-Huawei234cd092016-07-14 11:35:34 +0530665 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530666 T entity = getCurEntityToResolveFromStack();
667 if (entity instanceof YangIdentityRef || entity instanceof YangBase) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530668
669 //Check if name of node name matches with the current reference node.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530670 return curRefNode.getName().contentEquals(name);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530671 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530672 throw new DataModelException(getErrorMsg(
673 INVALID_ENTITY, curRefNode.getName(), curRefNode.getLineNumber(),
674 curRefNode.getCharPosition(), curRefNode.getFileName()));
Shankara-Huawei234cd092016-07-14 11:35:34 +0530675 }
676 }
677
678 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530679 * Checks for the referred node defined in a ancestor scope.
680 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530681 * @param refNode potential referred node
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530682 * @return status of resolution and updating the partial resolved stack with
683 * the any recursive references
janani b0e4e8ae2016-07-13 21:06:41 +0530684 * @throws DataModelException a violation of data model rules
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530685 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530686 private boolean isReferredNodeInSiblingListProcessed(YangNode refNode)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530687 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530688 while (refNode != null) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530689
690 // Check if the potential referred node is the actual referred node
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530691 if (isReferredNode(refNode)) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530692
693 // Adds reference link of entity to the node under resolution.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530694 addReferredEntityLink(refNode, LINKED);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530695
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530696 /*
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530697 * resolve the reference and update the partial resolution stack
698 * with any further recursive references
699 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530700 addUnresolvedRecursiveReferenceToStack(refNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530701
702 /*
703 * return true, since the reference is linked and any recursive
704 * unresolved references is added to the stack
705 */
706 return true;
707 }
708
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530709 refNode = refNode.getNextSibling();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530710 }
711 return false;
712 }
713
714 /**
715 * Checks if the potential referred node is the actual referred node.
716 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530717 * @param refNode typedef/grouping node
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530718 * @return true if node is of resolve type otherwise false
719 * @throws DataModelException a violation of data model rules
720 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530721 private boolean isReferredNode(YangNode refNode)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530722 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530723 T entity = getCurEntityToResolveFromStack();
724 if (entity instanceof YangType) {
725 if (refNode instanceof YangTypeDef) {
726 return isNodeNameSameAsResolutionInfoName(refNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530727 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530728 } else if (entity instanceof YangUses) {
729 if (refNode instanceof YangGrouping) {
730 return isNodeNameSameAsResolutionInfoName(refNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530731 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530732 } else if (entity instanceof YangIfFeature) {
733 if (refNode instanceof YangFeatureHolder) {
734 return isNodeNameSameAsResolutionInfoName(refNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530735 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530736 } else if (entity instanceof YangBase || entity instanceof YangIdentityRef) {
737 if (refNode instanceof YangIdentity) {
738 return isNodeNameSameAsResolutionInfoName(refNode);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530739 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530740 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530741 throw new DataModelException(getErrorMsg(
742 LINKER_ERROR, refNode.getName(), refNode.getLineNumber(),
743 refNode.getCharPosition(), refNode.getFileName()));
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530744 }
745 return false;
746 }
747
748 /**
749 * Checks if node name is same as name in resolution info, i.e. name of
750 * typedef/grouping is same as name of type/uses.
751 *
752 * @param node typedef/grouping node
753 * @return true if node name is same as name in resolution info, otherwise
754 * false
755 * @throws DataModelException a violation of data model rules
756 */
757
758 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
759 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530760 T entity = getCurEntityToResolveFromStack();
761 if (entity instanceof YangType) {
762 return node.getName().contentEquals(((YangType<?>) entity)
763 .getDataTypeName());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530764 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530765 if (entity instanceof YangUses) {
766 return node.getName().contentEquals(((YangUses) entity).getName());
767 }
768 if (entity instanceof YangIfFeature) {
769 return isFeatureDefinedInNode(node);
770 }
771 if (entity instanceof YangBase) {
772 return node.getName().contentEquals(((
773 YangBase) entity).getBaseIdentifier().getName());
774 }
775 if (entity instanceof YangIdentityRef) {
776 return node.getName().contentEquals(((YangIdentityRef) entity).getName());
777 }
778 throw new DataModelException(getErrorMsg(
779 INVALID_RESOLVED_ENTITY, node.getName(), node.getLineNumber(),
780 node.getCharPosition(), node.getFileName()));
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530781 }
782
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530783 private boolean isFeatureDefinedInNode(YangNode node) {
784 T entity = getCurEntityToResolveFromStack();
785 YangNodeIdentifier ifFeature = ((YangIfFeature) entity).getName();
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530786 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
787 if (featureList != null && !featureList.isEmpty()) {
788 Iterator<YangFeature> iterator = featureList.iterator();
789 while (iterator.hasNext()) {
790 YangFeature feature = iterator.next();
791 if (ifFeature.getName().equals(feature.getName())) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530792 ((YangIfFeature) entity).setReferredFeature(feature);
793 ((YangIfFeature) entity).setReferredFeatureHolder(node);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530794 return true;
795 }
796 }
797 }
798 return false;
799 }
800
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530801 /**
802 * Adds reference of grouping/typedef in uses/type.
803 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530804 * @param refNode grouping/typedef node being referred
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530805 * @param linkedStatus linked status if success.
806 * @throws DataModelException a violation of data model rules
807 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530808 private void addReferredEntityLink(YangNode refNode, ResolvableStatus linkedStatus)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530809 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530810 T entity = getCurEntityToResolveFromStack();
811 if (entity instanceof YangType) {
812 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((
813 YangType<?>) entity).getDataTypeExtendedInfo();
814 derivedInfo.setReferredTypeDef((YangTypeDef) refNode);
815 } else if (entity instanceof YangUses) {
816 ((YangUses) entity).setRefGroup((YangGrouping) refNode);
817 } else if (entity instanceof YangBase) {
818 ((YangBase) entity).setReferredIdentity((YangIdentity) refNode);
819 } else if (entity instanceof YangIdentityRef) {
820 ((YangIdentityRef) entity).setReferredIdentity((YangIdentity) refNode);
821 } else if (!(entity instanceof YangIfFeature) &&
822 !(entity instanceof YangLeafRef)) {
823 throw new DataModelException(getErrorMsg(
824 LINKER_ERROR, refNode.getName(), refNode.getLineNumber(),
825 refNode.getCharPosition(), refNode.getFileName()));
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530826 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530827 // Sets the resolution status in inside the type/uses.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530828 ((Resolvable) entity).setResolvableStatus(linkedStatus);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530829 }
830
831 /**
832 * Checks if type/grouping has further reference to typedef/ unresolved
833 * uses. Add it to the partial resolve stack and return the status of
834 * addition to stack.
835 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530836 * @param refNode grouping/typedef node
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530837 * @throws DataModelException a violation of data model rules
838 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530839 private void addUnresolvedRecursiveReferenceToStack(YangNode refNode)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530840 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530841 T entity = getCurEntityToResolveFromStack();
842 if (entity instanceof YangType) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530843
844 //Checks if typedef type is derived
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530845 if (((YangTypeDef) refNode).getTypeDefBaseType()
846 .getDataType() == YangDataTypes.DERIVED) {
847 addEntityToStack((T) ((YangTypeDef) refNode).getTypeDefBaseType(),
848 refNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530849 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530850 } else if (entity instanceof YangUses) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530851 /*
852 * Search if the grouping has any un resolved uses child, if so
853 * return true, else return false.
854 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530855 addUnResolvedUsesToStack(refNode);
856 } else if (entity instanceof YangIfFeature) {
857 addUnResolvedIfFeatureToStack(refNode);
858 } else if (entity instanceof YangLeafRef) {
janani b0e4e8ae2016-07-13 21:06:41 +0530859 // do nothing , referred node is already set
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530860 throw new DataModelException(getErrorMsg(
861 INVALID_RESOLVED_ENTITY, refNode.getName(), refNode.getLineNumber(),
862 refNode.getCharPosition(), refNode.getFileName()));
863 } else if (entity instanceof YangBase || entity instanceof YangIdentityRef) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530864
865 //Search if the identity has any un resolved base, if so return true, else return false.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530866 addUnResolvedBaseToStack(refNode);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530867 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530868 throw new DataModelException(getErrorMsg(
869 LINKER_ERROR, refNode.getName(), refNode.getLineNumber(),
870 refNode.getCharPosition(), refNode.getFileName()));
Bharat saraswale3175d32016-08-31 17:50:11 +0530871
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530872 }
873 }
874
875 /**
876 * Returns if there is any unresolved uses in grouping.
877 *
878 * @param node grouping/typedef node
879 */
880 private void addUnResolvedUsesToStack(YangNode node) {
881
Vidyashree Ramab3670472016-08-06 15:49:56 +0530882 //Search the grouping node's children for presence of uses node.
Vidyashree Rama72719fa2016-07-15 14:06:56 +0530883 TraversalType curTraversal = ROOT;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530884 YangNode curNode = node.getChild();
885 while (curNode != null) {
Vidyashree Rama72719fa2016-07-15 14:06:56 +0530886 if (curNode.getName().equals(node.getName())) {
887 // if we have traversed all the child nodes, then exit from loop
888 return;
889 }
890
891 // if child nodes has uses, then add it to resolution stack
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530892 if (curNode instanceof YangUses) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530893 addEntityToStack((T) curNode, node);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530894 }
Vidyashree Rama72719fa2016-07-15 14:06:56 +0530895
896 // Traversing all the child nodes of grouping
897 if (curTraversal != PARENT && curNode.getChild() != null) {
898 curTraversal = CHILD;
899 curNode = curNode.getChild();
900 } else if (curNode.getNextSibling() != null) {
901 curTraversal = SIBILING;
902 curNode = curNode.getNextSibling();
903 } else {
904 curTraversal = PARENT;
905 curNode = curNode.getParent();
906 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530907 }
908 }
909
910 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530911 * Returns if there is any unresolved if-feature in feature.
912 *
913 * @param node module/submodule node
914 */
915 private void addUnResolvedIfFeatureToStack(YangNode node) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530916 YangFeature refFeature = ((YangIfFeature) getCurEntityToResolveFromStack())
917 .getReferredFeature();
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530918 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
919 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
920 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
921 while (ifFeatureIterator.hasNext()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530922 addEntityToStack((T) ifFeatureIterator.next(), node);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530923 }
924 }
925 }
926
927 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530928 * Returns if there is any unresolved base in identity.
929 *
930 * @param node module/submodule node
931 */
932 private void addUnResolvedBaseToStack(YangNode node) {
933
934 YangIdentity curNode = (YangIdentity) node;
935 if (curNode.getBaseNode() != null) {
936 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530937 addEntityToStack((T) curNode.getBaseNode(), node);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530938 }
939 }
940 }
941
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530942 private void addEntityToStack(T entity, YangNode holder) {
943 YangEntityToResolveInfoImpl<T> unResolvedEntityInfo =
944 new YangEntityToResolveInfoImpl<>();
945 unResolvedEntityInfo.setEntityToResolve(entity);
946 unResolvedEntityInfo.setHolderOfEntityToResolve(holder);
947 addInPartialResolvedStack(unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530948 }
949
950 /**
951 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
952 *
953 * @param partialResolvedInfo partial resolved YANG construct stack
954 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530955 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530956 partialResolvedStack.push(partialResolvedInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530957 }
958
959 /**
960 * Retrieves the next entity in the stack that needs to be resolved. It is
961 * assumed that the caller ensures that the stack is not empty.
962 *
963 * @return next entity in the stack that needs to be resolved
964 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530965 private T getCurEntityToResolveFromStack() {
966 return partialResolvedStack.peek().getEntityToResolve();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530967 }
968
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530969 @Override
970 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530971 return entityToResolveInfo;
972 }
973
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530974 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530975 public void linkInterFile(YangReferenceResolver dataModelRootNode)
976 throws DataModelException {
977
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530978 curRefResolver = dataModelRootNode;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530979
980 // Current node to resolve, it can be a YANG type or YANG uses.
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530981 T entityToResolve = entityToResolveInfo.getEntityToResolve();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530982
983 // Check if linking is already done
984 if (entityToResolve instanceof Resolvable) {
985 Resolvable resolvable = (Resolvable) entityToResolve;
986 if (resolvable.getResolvableStatus() == RESOLVED) {
987 return;
988 }
989 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530990 throw new DataModelException(UNRESOLVABLE);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530991 }
992
Bharat saraswal9fab16b2016-09-23 23:27:24 +0530993 if (entityToResolve instanceof YangXPathResolver &&
994 !(entityToResolve instanceof YangLeafRef)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530995 //Process x-path linking.
janani bebb143d2016-07-14 19:35:22 +0530996 processXPathLinking(entityToResolve, dataModelRootNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530997
Bharat saraswald14cbe82016-07-14 13:26:18 +0530998 } else {
Bharat saraswald14cbe82016-07-14 13:26:18 +0530999 // Push the initial entity to resolve in stack.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301000 addInPartialResolvedStack(entityToResolveInfo);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301001 // Inter file linking and resolution.
1002 linkInterFileAndResolve();
Bharat saraswald14cbe82016-07-14 13:26:18 +05301003 addDerivedRefTypeToRefTypeResolutionList();
1004 }
1005 }
1006
1007 /**
1008 * Process x-path linking for augment and leaf-ref.
1009 *
janani bebb143d2016-07-14 19:35:22 +05301010 * @param entityToResolve entity to resolve
1011 * @param root root node
janani b3a3e3262016-10-19 00:23:28 +05301012 * @throws DataModelException if there is a data model error
Bharat saraswald14cbe82016-07-14 13:26:18 +05301013 */
janani bebb143d2016-07-14 19:35:22 +05301014 private void processXPathLinking(T entityToResolve,
janani b3a3e3262016-10-19 00:23:28 +05301015 YangReferenceResolver root)
1016 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301017
Bharat saraswald14cbe82016-07-14 13:26:18 +05301018 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
janani bebb143d2016-07-14 19:35:22 +05301019
Bharat saraswald14cbe82016-07-14 13:26:18 +05301020 if (entityToResolve instanceof YangAugment) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301021 YangNode targetNode;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301022 YangAugment augment = (YangAugment) entityToResolve;
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301023 targetNode = xPathLinker
Bharat saraswal94844d62016-10-13 13:28:03 +05301024 .processXpathLinking(augment.getTargetNode(), (YangNode)
1025 root, AUGMENT_LINKING);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301026 if (targetNode != null) {
1027 if (targetNode instanceof YangAugmentableNode) {
1028 detectCollisionForAugmentedNode(targetNode, augment);
1029 ((YangAugmentableNode) targetNode).addAugmentation(augment);
1030 augment.setAugmentedNode(targetNode);
Vidyashree Ramab20ba9e2016-09-02 14:12:25 +05301031 setAugmentedFlagInAncestors(targetNode);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301032 Resolvable resolvable = (Resolvable) entityToResolve;
1033 resolvable.setResolvableStatus(RESOLVED);
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301034 if (targetNode instanceof YangInput) {
1035 xPathLinker.addInModuleIfInput(augment, (YangNode) root);
1036 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301037 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301038 throw new LinkerException(getErrorMsg(
1039 INVALID_TARGET + targetNode.getNodeType(),
1040 augment.getName(), augment.getLineNumber(),
1041 augment.getCharPosition(), augment.getFileName()));
Bharat saraswald14cbe82016-07-14 13:26:18 +05301042 }
1043 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301044 throw new LinkerException(getErrorMsg(
1045 FAILED_TO_LINK, augment.getName(), augment
1046 .getLineNumber(), augment.getCharPosition(),
1047 augment.getFileName()));
Bharat saraswald14cbe82016-07-14 13:26:18 +05301048 }
Vidyashree Ramab3670472016-08-06 15:49:56 +05301049 } else if (entityToResolve instanceof YangCompilerAnnotation) {
1050 YangNode targetNode;
1051 YangCompilerAnnotation ca = (YangCompilerAnnotation) entityToResolve;
Bharat saraswal94844d62016-10-13 13:28:03 +05301052 targetNode = xPathLinker.processXpathLinking(ca.getAtomicPathList(),
1053 (YangNode) root,
1054 AUGMENT_LINKING);
Vidyashree Ramab3670472016-08-06 15:49:56 +05301055 if (targetNode != null) {
1056 if (targetNode instanceof YangList) {
1057 ((YangList) targetNode).setCompilerAnnotation(
1058 (YangCompilerAnnotation) entityToResolve);
1059 Resolvable resolvable = (Resolvable) entityToResolve;
1060 resolvable.setResolvableStatus(RESOLVED);
1061 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301062 throw new LinkerException(getErrorMsg(
1063 INVALID_TARGET + targetNode.getNodeType(), ca.getPath(),
1064 ca.getLineNumber(), ca.getCharPosition(), ca.getFileName()));
Vidyashree Ramab3670472016-08-06 15:49:56 +05301065 }
1066 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301067 throw new LinkerException(getErrorMsg(
1068 FAILED_TO_FIND_ANNOTATION, ca.getPath(), ca.getLineNumber(),
1069 ca.getCharPosition(), ca.getFileName()));
Vidyashree Ramab3670472016-08-06 15:49:56 +05301070 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301071 } else if (entityToResolve instanceof YangLeafRef) {
1072 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301073 Object target = xPathLinker.processLeafRefXpathLinking(
Bharat saraswal94844d62016-10-13 13:28:03 +05301074 leafRef.getAtomicPath(), (YangNode) root, leafRef, LEAF_REF_LINKING);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301075 if (target != null) {
Bharat saraswale3175d32016-08-31 17:50:11 +05301076 YangLeaf leaf;
1077 YangLeafList leafList;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301078 leafRef.setReferredLeafOrLeafList(target);
1079 if (target instanceof YangLeaf) {
1080 leaf = (YangLeaf) target;
janani bebb143d2016-07-14 19:35:22 +05301081 leafRef.setResolvableStatus(INTER_FILE_LINKED);
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301082 addUnResolvedLeafRefTypeToStack((T) leaf, entityToResolveInfo
1083 .getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301084 } else {
1085 leafList = (YangLeafList) target;
janani bebb143d2016-07-14 19:35:22 +05301086 leafRef.setResolvableStatus(INTER_FILE_LINKED);
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301087 addUnResolvedLeafRefTypeToStack(
1088 (T) leafList, entityToResolveInfo.getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301089 }
janani b3a3e3262016-10-19 00:23:28 +05301090 fillPathPredicates(leafRef);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301091 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301092 LinkerException ex = new LinkerException(
1093 FAILED_TO_FIND_LEAD_INFO_HOLDER + leafRef.getPath());
1094 ex.setCharPosition(leafRef.getCharPosition());
1095 ex.setLine(leafRef.getLineNumber());
1096 ex.setFileName(leafRef.getFileName());
1097 throw ex;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301098 }
1099 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301100 }
1101
1102 /**
1103 * Returns the referenced prefix of entity under resolution.
1104 *
1105 * @return referenced prefix of entity under resolution
1106 * @throws DataModelException a violation in data model rule
1107 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301108 private String getRefPrefix()
1109 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301110 T entity = getCurEntityToResolveFromStack();
1111 if (entity instanceof YangType) {
1112 return ((YangType<?>) entity).getPrefix();
janani b0e4e8ae2016-07-13 21:06:41 +05301113 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301114 if (entity instanceof YangUses) {
1115 return ((YangUses) entity).getPrefix();
1116 }
1117 if (entity instanceof YangIfFeature) {
1118 return ((YangIfFeature) entity).getPrefix();
1119 }
1120 if (entity instanceof YangBase) {
1121 return ((YangBase) entity).getBaseIdentifier()
1122 .getPrefix();
1123 }
1124 if (entity instanceof YangIdentityRef) {
1125 return ((YangIdentityRef) entity).getPrefix();
1126 }
1127 throw new DataModelException(LINKER_ERROR);
janani b0e4e8ae2016-07-13 21:06:41 +05301128 }
1129
1130 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301131 * Performs inter file linking and resolution.
1132 *
1133 * @throws DataModelException a violation in data model rule
1134 */
1135 private void linkInterFileAndResolve()
1136 throws DataModelException {
1137
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301138 while (!partialResolvedStack.isEmpty()) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301139
1140 // Current node to resolve, it can be a YANG type or YANG uses.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301141 T entityToResolve = getCurEntityToResolveFromStack();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301142 // Check if linking is already done
1143 if (entityToResolve instanceof Resolvable) {
1144
1145 Resolvable resolvable = (Resolvable) entityToResolve;
1146 switch (resolvable.getResolvableStatus()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301147 case RESOLVED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301148 /*
1149 * If the entity is already resolved in the stack, then pop
1150 * it and continue with the remaining stack elements to
1151 * resolve
1152 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301153 partialResolvedStack.pop();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301154 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301155
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301156 case INTER_FILE_LINKED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301157 /*
1158 * If the top of the stack is already linked then resolve
1159 * the references and pop the entity and continue with
1160 * remaining stack elements to resolve
1161 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301162 resolveTopOfStack();
1163 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 INTRA_FILE_RESOLVED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301167 /*
1168 * If the top of the stack is intra file resolved then check
1169 * if top of stack is linked, if not link it using
1170 * import/include list and push the linked referred entity
1171 * to the stack, otherwise only push it to the stack.
1172 */
1173 linkInterFileTopOfStackRefUpdateStack();
1174 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301175
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301176 case UNDEFINED:
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301177 /*
1178 * In case of if-feature resolution, if referred "feature" is not
1179 * defined then the resolvable status will be undefined.
1180 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301181 partialResolvedStack.pop();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301182 break;
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301183
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301184 default:
1185 throw new DataModelException(INVALID_LINKER_STATE);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301186 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301187 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301188 throw new DataModelException(INVALID_RESOLVED_ENTITY);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301189 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301190 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301191 }
1192
1193 /**
1194 * Links the top of the stack if it's inter-file and update stack.
1195 *
1196 * @throws DataModelException data model error
1197 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301198 private void linkInterFileTopOfStackRefUpdateStack()
1199 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301200 T entity = getCurEntityToResolveFromStack();
1201 if (entity instanceof YangLeafRef) {
janani bebb143d2016-07-14 19:35:22 +05301202 // When leafref path comes with relative path, it will be converted to absolute path.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301203 setAbsolutePathFromRelativePathInLeafref(entity);
1204 processXPathLinking(entity, curRefResolver);
janani bebb143d2016-07-14 19:35:22 +05301205 return;
1206 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301207 /*
1208 * Obtain the referred node of top of stack entity under resolution
1209 */
Bharat saraswal94844d62016-10-13 13:28:03 +05301210 T refNode = getRefNode();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301211
1212 /*
1213 * Check for null for scenario when it's not linked and inter-file
1214 * linking is required.
1215 */
Bharat saraswal94844d62016-10-13 13:28:03 +05301216 if (refNode == null) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301217
1218 /*
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301219 * Check if prefix is null or not, to identify whether to search in
1220 * import list or include list.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301221 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301222 if (getRefPrefix() != null && !getRefPrefix()
1223 .contentEquals(curRefResolver.getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301224 if (resolveWithImport()) {
1225 return;
1226 }
1227 } else {
1228 if (resolveWithInclude()) {
1229 return;
1230 }
1231 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301232
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301233 if (entity instanceof YangIfFeature) {
1234 ((YangIfFeature) entity).setResolvableStatus(UNDEFINED);
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301235 return;
1236 }
janani b0e4e8ae2016-07-13 21:06:41 +05301237 // If current entity is still not resolved, then
1238 // linking/resolution has failed.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301239
1240 DataModelException ex = new DataModelException(
1241 getErrorInfoForLinker(entity));
1242 ex.setLine(getLineNumber());
1243 ex.setCharPosition(getCharPosition());
1244 throw ex;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301245 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301246 ((Resolvable) entity).setResolvableStatus(INTER_FILE_LINKED);
Bharat saraswal94844d62016-10-13 13:28:03 +05301247 addUnresolvedRecursiveReferenceToStack((YangNode) refNode);
janani bebb143d2016-07-14 19:35:22 +05301248 }
1249 }
1250
1251 /**
1252 * Sets the leafref with absolute path from the relative path.
1253 *
1254 * @param resolutionInfo information about the YANG construct which has to be resolved
1255 * @throws DataModelException a violation of data model rules
1256 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301257 private void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301258 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301259 if (resolutionInfo instanceof YangLeafRef) {
1260
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301261 YangNode leafParent = ((YangLeafRef) resolutionInfo)
janani b3a3e3262016-10-19 00:23:28 +05301262 .getParentNode();
janani bebb143d2016-07-14 19:35:22 +05301263 YangLeafRef leafref = (YangLeafRef) resolutionInfo;
1264
1265 // Checks if the leafref has relative path in it.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301266 if (leafref.getPathType() == RELATIVE_PATH) {
janani bebb143d2016-07-14 19:35:22 +05301267 YangRelativePath relativePath = leafref.getRelativePath();
1268 List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301269 int ancestorCount = relativePath.getAncestorNodeCount();
janani bebb143d2016-07-14 19:35:22 +05301270
1271 // Gets the root node from the ancestor count.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301272 T nodeOrAugmentList =
1273 getRootNodeWithAncestorCountForLeafref(ancestorCount, leafParent,
1274 leafref);
janani bebb143d2016-07-14 19:35:22 +05301275 if (nodeOrAugmentList instanceof YangNode) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301276 StringBuilder name = new StringBuilder();
1277 StringBuilder prefix = new StringBuilder();
janani bebb143d2016-07-14 19:35:22 +05301278 YangNode rootNode = (YangNode) nodeOrAugmentList;
1279 // Forms a new absolute path from the relative path
1280 while (!(rootNode instanceof YangReferenceResolver)) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301281 name.append(rootNode.getName());
1282 prefix.append(SLASH_FOR_STRING).append(name.reverse());
1283 name.delete(0, name.length());
janani bebb143d2016-07-14 19:35:22 +05301284 rootNode = rootNode.getParent();
1285 if (rootNode == null) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301286 throw new DataModelException(INVALID_TREE);
janani bebb143d2016-07-14 19:35:22 +05301287 }
1288 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301289 prefix.reverse();
1290 fillAbsolutePathValuesInLeafref(leafref, prefix.toString(),
1291 absoluteInRelative);
janani bebb143d2016-07-14 19:35:22 +05301292 } else {
1293 List<String> listOfAugment = (List<String>) nodeOrAugmentList;
1294 Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301295 StringBuilder augment = new StringBuilder(EMPTY_STRING);
janani bebb143d2016-07-14 19:35:22 +05301296 while (listOfAugmentIterator.hasNext()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301297 augment.append(SLASH_FOR_STRING)
1298 .append(listOfAugmentIterator.next());
janani bebb143d2016-07-14 19:35:22 +05301299 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301300 fillAbsolutePathValuesInLeafref(leafref, augment.toString(),
1301 absoluteInRelative);
janani b0e4e8ae2016-07-13 21:06:41 +05301302 }
janani b0e4e8ae2016-07-13 21:06:41 +05301303 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301304 }
1305 }
1306
1307 /**
janani bebb143d2016-07-14 19:35:22 +05301308 * Fills the absolute path values in the leafref from relative path.
1309 *
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301310 * @param leafref instance of YANG leafref
1311 * @param path path name which has to be prefixed to relative path
1312 * @param relative atomic paths in relative
janani bebb143d2016-07-14 19:35:22 +05301313 * @throws DataModelException a violation of data model rules
1314 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301315 private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String path,
1316 List<YangAtomicPath> relative)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301317 throws DataModelException {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301318 leafref.setPathType(ABSOLUTE_PATH);
janani bebb143d2016-07-14 19:35:22 +05301319 String[] pathName = new String[0];
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301320 if (path != null && !path.equals(EMPTY_STRING)) {
1321 pathName = path.split(SLASH_FOR_STRING);
janani bebb143d2016-07-14 19:35:22 +05301322 }
1323 List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
1324 for (String value : pathName) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301325 if (value != null && !value.isEmpty() && !value.equals(EMPTY_STRING)) {
1326 YangNodeIdentifier nodeId = getValidNodeIdentifier(value, PATH_DATA);
janani bebb143d2016-07-14 19:35:22 +05301327 YangAtomicPath atomicPath = new YangAtomicPath();
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301328 atomicPath.setNodeIdentifier(nodeId);
janani bebb143d2016-07-14 19:35:22 +05301329 finalListForAbsolute.add(atomicPath);
1330 }
1331 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301332 if (relative != null && !relative.isEmpty()) {
1333 Iterator<YangAtomicPath> pathIt = relative.listIterator();
1334 while (pathIt.hasNext()) {
1335 YangAtomicPath yangAtomicPath = pathIt.next();
janani bebb143d2016-07-14 19:35:22 +05301336 finalListForAbsolute.add(yangAtomicPath);
1337 }
1338 leafref.setAtomicPath(finalListForAbsolute);
1339 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301340 DataModelException ex = new DataModelException(getLeafRefErrorInfo(leafref));
1341 ex.setCharPosition(leafref.getCharPosition());
1342 ex.setLine(leafref.getLineNumber());
1343 ex.setFileName(leafref.getFileName());
1344 throw ex;
janani bebb143d2016-07-14 19:35:22 +05301345 }
1346 }
1347
1348 /**
1349 * Returns the root parent with respect to the ancestor count from leafref.
1350 *
1351 * @param ancestorCount count of node where parent node can be reached
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301352 * @param curParent current parent node
janani bebb143d2016-07-14 19:35:22 +05301353 * @param leafref instance of YANG leafref
1354 * @return node where the ancestor count stops or augment path name list
1355 * @throws DataModelException a violation of data model rules
1356 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301357 private T getRootNodeWithAncestorCountForLeafref(
1358 int ancestorCount, YangNode curParent, YangLeafRef leafref)
janani bebb143d2016-07-14 19:35:22 +05301359 throws DataModelException {
1360
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301361 int curParentCount = 1;
1362 curParent = skipInvalidDataNodes(curParent, leafref);
1363 if (curParent instanceof YangAugment) {
1364 YangAugment augment = (YangAugment) curParent;
1365 List<String> valueInAugment = getPathWithAugment(augment,
1366 ancestorCount - curParentCount);
janani bebb143d2016-07-14 19:35:22 +05301367 return (T) valueInAugment;
1368 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301369 while (curParentCount < ancestorCount) {
1370 YangNode currentSkippedParent = skipInvalidDataNodes(curParent, leafref);
1371 if (currentSkippedParent == curParent) {
1372 if (curParent.getParent() == null) {
1373 throw new DataModelException(getLeafRefErrorInfo(leafref));
janani bebb143d2016-07-14 19:35:22 +05301374 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301375 curParent = curParent.getParent();
janani bebb143d2016-07-14 19:35:22 +05301376 } else {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301377 curParent = currentSkippedParent;
janani bebb143d2016-07-14 19:35:22 +05301378 continue;
1379 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301380 curParentCount = curParentCount + 1;
1381 if (curParent instanceof YangAugment) {
1382 YangAugment augment = (YangAugment) curParent;
1383 List<String> valueInAugment = getPathWithAugment(
1384 augment, ancestorCount - curParentCount);
janani bebb143d2016-07-14 19:35:22 +05301385 return (T) valueInAugment;
1386 }
1387 }
1388 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301389 return (T) curParent;
janani bebb143d2016-07-14 19:35:22 +05301390 }
1391
1392 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301393 * Finds and resolves with include list.
1394 *
1395 * @return true if resolved, false otherwise
1396 * @throws DataModelException a violation in data model rule
1397 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301398 private boolean resolveWithInclude() throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301399 /*
1400 * Run through all the nodes in include list and search for referred
1401 * typedef/grouping at the root level.
1402 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301403 for (YangInclude yangInclude : curRefResolver.getIncludeList()) {
1404 YangNode linkedNode = getLinkedNode(yangInclude.getIncludedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301405 if (linkedNode != null) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301406 return addUnResolvedRefToStack(linkedNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301407 }
1408 }
1409 // If referred node can't be found return false.
1410 return false;
1411 }
1412
1413 /**
1414 * Finds and resolves with import list.
1415 *
1416 * @return true if resolved, false otherwise
1417 * @throws DataModelException a violation in data model rule
1418 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301419 private boolean resolveWithImport() throws DataModelException {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301420
1421 // Run through import list to find the referred typedef/grouping.
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301422 for (YangImport yangImport : curRefResolver.getImportList()) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301423 /*
1424 * Match the prefix attached to entity under resolution with the
1425 * imported/included module/sub-module's prefix. If found, search
1426 * for the referred typedef/grouping at the root level.
1427 */
1428 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301429 YangNode linkedNode = getLinkedNode(yangImport.getImportedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301430 if (linkedNode != null) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301431 return addUnResolvedRefToStack(linkedNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301432 }
1433 /*
1434 * If referred node can't be found at root level break for loop,
1435 * and return false.
1436 */
1437 break;
1438 }
1439 }
1440 // If referred node can't be found return false.
1441 return false;
1442 }
1443
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301444 //Add unresolved constructs to stack.
1445 private boolean addUnResolvedRefToStack(YangNode linkedNode)
1446 throws DataModelException {
1447 // Add the link to external entity.
1448 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
1449
1450 // Add the type/uses of referred typedef/grouping to the stack.
1451 addUnresolvedRecursiveReferenceToStack(linkedNode);
1452 return true;
1453 }
1454
1455 //Returns linked node from entity of stack.
1456 private YangNode getLinkedNode(YangNode node) {
1457 T entity = getCurEntityToResolveFromStack();
1458 if (entity instanceof YangType) {
1459 return findRefTypedef(node);
1460 }
1461 if (entity instanceof YangUses) {
1462 return findRefGrouping(node);
1463 }
1464 if (entity instanceof YangIfFeature) {
1465 return findRefFeature(node);
1466 }
1467 if (entity instanceof YangBase) {
1468 return findRefIdentity(node);
1469 }
1470 if (entity instanceof YangIdentityRef) {
1471 return findRefIdentityRef(node);
1472 }
1473 return null;
1474 }
1475
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301476 /**
1477 * Returns referred typedef/grouping node.
1478 *
1479 * @return referred typedef/grouping node
1480 * @throws DataModelException a violation in data model rule
1481 */
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301482 private T getRefNode() throws DataModelException {
1483 T entity = getCurEntityToResolveFromStack();
1484 if (entity instanceof YangType) {
1485 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>)
1486 ((YangType<?>) entity).getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301487 return (T) derivedInfo.getReferredTypeDef();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301488 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301489 if (entity instanceof YangUses) {
1490 return (T) ((YangUses) entity).getRefGroup();
1491 }
1492 if (entity instanceof YangIfFeature) {
1493 return (T) ((YangIfFeature) entity).getReferredFeatureHolder();
1494 }
1495 if (entity instanceof YangLeafRef) {
1496 return (T) ((YangLeafRef) entity).getReferredLeafOrLeafList();
1497 }
1498 if (entity instanceof YangBase) {
1499 return (T) ((YangBase) entity).getReferredIdentity();
1500 }
1501 if (entity instanceof YangIdentityRef) {
1502 return (T) ((YangIdentityRef) entity).getReferredIdentity();
1503 }
1504 throw new DataModelException(LINKER_ERROR);
1505
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301506 }
1507
1508 /**
1509 * Finds the referred grouping node at the root level of imported/included node.
1510 *
1511 * @param refNode module/sub-module node
1512 * @return referred grouping
1513 */
1514 private YangNode findRefGrouping(YangNode refNode) {
1515 YangNode tmpNode = refNode.getChild();
1516 while (tmpNode != null) {
1517 if (tmpNode instanceof YangGrouping) {
1518 if (tmpNode.getName()
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301519 .equals(((YangUses) getCurEntityToResolveFromStack())
1520 .getName())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301521 return tmpNode;
1522 }
1523 }
1524 tmpNode = tmpNode.getNextSibling();
1525 }
1526 return null;
1527 }
1528
1529 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301530 * Finds the referred feature node at the root level of imported/included node.
1531 *
1532 * @param refNode module/sub-module node
1533 * @return referred feature
1534 */
1535 private YangNode findRefFeature(YangNode refNode) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301536 T entity = getCurEntityToResolveFromStack();
1537 YangNodeIdentifier ifFeature = ((YangIfFeature) entity).getName();
1538 List<YangFeature> featureList = ((YangFeatureHolder) refNode)
1539 .getFeatureList();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301540 if (featureList != null && !featureList.isEmpty()) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301541 for (YangFeature feature : featureList) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301542 if (ifFeature.getName().equals(feature.getName())) {
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301543 ((YangIfFeature) entity).setReferredFeature(feature);
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301544 return refNode;
1545 }
1546 }
1547 }
1548 return null;
1549 }
1550
1551 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301552 * Finds the referred typedef node at the root level of imported/included node.
1553 *
1554 * @param refNode module/sub-module node
1555 * @return referred typedef
1556 */
1557 private YangNode findRefTypedef(YangNode refNode) {
1558 YangNode tmpNode = refNode.getChild();
1559 while (tmpNode != null) {
1560 if (tmpNode instanceof YangTypeDef) {
1561 if (tmpNode.getName()
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301562 .equals(((YangType) getCurEntityToResolveFromStack())
1563 .getDataTypeName())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301564 return tmpNode;
1565 }
1566 }
1567 tmpNode = tmpNode.getNextSibling();
1568 }
1569 return null;
1570 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301571
1572 /**
1573 * Finds the referred identity node at the root level of imported/included node.
1574 *
1575 * @param refNode module/sub-module node
1576 * @return referred identity
1577 */
1578 private YangNode findRefIdentity(YangNode refNode) {
1579 YangNode tmpNode = refNode.getChild();
1580 while (tmpNode != null) {
1581 if (tmpNode instanceof YangIdentity) {
1582 if (tmpNode.getName()
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301583 .equals(((YangBase) getCurEntityToResolveFromStack())
1584 .getBaseIdentifier().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301585 return tmpNode;
1586 }
1587 }
1588 tmpNode = tmpNode.getNextSibling();
1589 }
1590 return null;
1591 }
1592
1593 /**
1594 * Finds the referred identity node at the root level of imported/included node.
1595 *
1596 * @param refNode module/sub-module node
1597 * @return referred identity
1598 */
1599 private YangNode findRefIdentityRef(YangNode refNode) {
1600 YangNode tmpNode = refNode.getChild();
1601 while (tmpNode != null) {
1602 if (tmpNode instanceof YangIdentity) {
1603 if (tmpNode.getName()
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301604 .equals(((YangIdentityRef) getCurEntityToResolveFromStack())
1605 .getBaseIdentity().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301606 return tmpNode;
1607 }
1608 }
1609 tmpNode = tmpNode.getNextSibling();
1610 }
1611 return null;
1612 }
Bharat saraswal2da23bf2016-08-25 15:28:39 +05301613
Vidyashree Ramab20ba9e2016-09-02 14:12:25 +05301614 /**
1615 * Sets descendant node augmented flag in ancestors.
1616 *
1617 * @param targetNode augmented YANG node
1618 */
1619 private void setAugmentedFlagInAncestors(YangNode targetNode) {
1620 targetNode = targetNode.getParent();
1621 while (targetNode != null) {
1622 targetNode.setDescendantNodeAugmented(true);
1623 targetNode = targetNode.getParent();
1624 }
1625 }
Bharat saraswal9fab16b2016-09-23 23:27:24 +05301626}