blob: eb42233a2448bfe1e54cbb16440254c6d57f1551 [file] [log] [blame]
Gaurav Agrawal0d43bb52016-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 saraswal96dfef02016-06-16 00:29:12 +053019import java.io.Serializable;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053020import java.util.Iterator;
21import java.util.List;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053022import java.util.Stack;
Bharat saraswal96dfef02016-06-16 00:29:12 +053023
24import org.onosproject.yangutils.datamodel.Resolvable;
janani be18b5342016-07-13 21:06:41 +053025import org.onosproject.yangutils.datamodel.ResolvableType;
26import org.onosproject.yangutils.datamodel.YangAtomicPath;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053027import org.onosproject.yangutils.datamodel.YangBase;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053028import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053029import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
30import org.onosproject.yangutils.datamodel.YangFeature;
31import org.onosproject.yangutils.datamodel.YangFeatureHolder;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053032import org.onosproject.yangutils.datamodel.YangGrouping;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053033import org.onosproject.yangutils.datamodel.YangIfFeature;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053034import org.onosproject.yangutils.datamodel.YangIdentity;
35import org.onosproject.yangutils.datamodel.YangIdentityRef;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053036import org.onosproject.yangutils.datamodel.YangImport;
37import org.onosproject.yangutils.datamodel.YangInclude;
janani be18b5342016-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;
42import org.onosproject.yangutils.datamodel.YangLeavesHolder;
43import org.onosproject.yangutils.datamodel.YangList;
44import org.onosproject.yangutils.datamodel.YangModule;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053045import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053046import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
janani be18b5342016-07-13 21:06:41 +053047import org.onosproject.yangutils.datamodel.YangOutput;
48import org.onosproject.yangutils.datamodel.YangPathArgType;
49import org.onosproject.yangutils.datamodel.YangPathPredicate;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053050import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani be18b5342016-07-13 21:06:41 +053051import org.onosproject.yangutils.datamodel.YangRelativePath;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053052import org.onosproject.yangutils.datamodel.YangResolutionInfo;
janani be18b5342016-07-13 21:06:41 +053053import org.onosproject.yangutils.datamodel.YangRpc;
54import org.onosproject.yangutils.datamodel.YangSubModule;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053055import org.onosproject.yangutils.datamodel.YangType;
56import org.onosproject.yangutils.datamodel.YangTypeDef;
57import org.onosproject.yangutils.datamodel.YangUses;
58import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswal96dfef02016-06-16 00:29:12 +053059import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
janani be18b5342016-07-13 21:06:41 +053060import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +053061import org.onosproject.yangutils.linker.YangLinkingPhase;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053062
Bharat saraswal96dfef02016-06-16 00:29:12 +053063import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
64import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
65import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
66import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053067import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNDEFINED;
Bharat saraswal96dfef02016-06-16 00:29:12 +053068import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +053069import static org.onosproject.yangutils.linker.YangLinkingPhase.INTER_FILE;
70import static org.onosproject.yangutils.linker.YangLinkingPhase.INTRA_FILE;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053071import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
Vidyashree Rama210c01d2016-05-20 16:29:25 +053072import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +053073import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
74import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053075import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
janani be18b5342016-07-13 21:06:41 +053076import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
77import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053078import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053079import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF_LINKER_ERROR;
80import static org.onosproject.yangutils.utils.UtilConstants.BASE_LINKER_ERROR;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053081
82/**
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053083 * Represents implementation of resolution object which will be resolved by
84 * linker.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053085 *
86 * @param <T> type of resolution entity uses / type
87 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053088public class YangResolutionInfoImpl<T>
Bharat saraswal96dfef02016-06-16 00:29:12 +053089 implements YangResolutionInfo<T>, Serializable {
90
91 private static final long serialVersionUID = 806201658L;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053092
93 /**
94 * Information about the entity that needs to be resolved.
95 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053096 private YangEntityToResolveInfoImpl<T> entityToResolveInfo;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053097
98 /**
99 * Error line number.
100 */
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530101 private transient int lineNumber;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530102
103 /**
104 * Error character position in number.
105 */
Bharat saraswal96dfef02016-06-16 00:29:12 +0530106 private transient int charPosition;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530107
108 /**
109 * Current module/sub-module reference, will be used in inter-file/
110 * inter-jar scenario to get the import/include list.
111 */
Bharat saraswal96dfef02016-06-16 00:29:12 +0530112 private transient YangReferenceResolver curReferenceResolver;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530113
114 /**
115 * Stack for type/uses is maintained for hierarchical references, this is
116 * used during resolution.
117 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530118 private Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530119
120 /**
121 * It is private to ensure the overloaded method be invoked to create an
122 * object.
123 */
124 @SuppressWarnings("unused")
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530125 private YangResolutionInfoImpl() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530126
127 }
128
129 /**
130 * Creates a resolution information object with all the inputs.
131 *
132 * @param dataNode current parsable data node
133 * @param holderNode parent YANG node
134 * @param lineNumber error line number
135 * @param charPositionInLine error character position in line
136 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530137 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
138 setEntityToResolveInfo(new YangEntityToResolveInfoImpl<>());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530139 getEntityToResolveInfo().setEntityToResolve(dataNode);
140 getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
141 this.setLineNumber(lineNumber);
142 this.setCharPosition(charPositionInLine);
143 setPartialResolvedStack(new Stack<>());
144 }
145
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530146 @Override
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530147 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
148 throws DataModelException {
149
150 setCurReferenceResolver(dataModelRootNode);
151
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530152 /**
153 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
154 * YANG leafref or YANG base or YANG identityref.
155 */
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530156 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
157
158 // Check if linking is already done
159 if (entityToResolve instanceof Resolvable) {
160 Resolvable resolvable = (Resolvable) entityToResolve;
161 if (resolvable.getResolvableStatus() == RESOLVED) {
162 /**
163 * entity is already resolved, so nothing to do
164 */
165 return;
166 }
167 } else {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530168 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530169 "type/uses/if-feature/leafref/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530170 }
171
172 // Push the initial entity to resolve in stack.
173 addInPartialResolvedStack(getEntityToResolveInfo());
174
175 linkAndResolvePartialResolvedStack();
janani be18b5342016-07-13 21:06:41 +0530176
177 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530178 }
179
180 /**
181 * Resolves linking with ancestors.
182 *
183 * @throws DataModelException a violation of data model rules
184 */
185 private void linkAndResolvePartialResolvedStack()
186 throws DataModelException {
187
188 while (getPartialResolvedStack().size() != 0) {
189
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530190 /**
191 * Current node to resolve, it can be a YANG type or YANG uses or
192 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
193 */
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530194 T entityToResolve = getCurrentEntityToResolveFromStack();
195 // Check if linking is already done
196 if (entityToResolve instanceof Resolvable) {
197
198 Resolvable resolvable = (Resolvable) entityToResolve;
199 switch (resolvable.getResolvableStatus()) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530200 case RESOLVED: {
201 /*
202 * If the entity is already resolved in the stack, then pop
203 * it and continue with the remaining stack elements to
204 * resolve
205 */
206 getPartialResolvedStack().pop();
207 break;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530208 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530209
210 case LINKED: {
211 /*
212 * If the top of the stack is already linked then resolve
213 * the references and pop the entity and continue with
214 * remaining stack elements to resolve.
215 */
216 resolveTopOfStack(INTRA_FILE);
217 getPartialResolvedStack().pop();
218 break;
219 }
220
221 case INTRA_FILE_RESOLVED: {
222 /*
223 * Pop the top of the stack.
224 */
225 getPartialResolvedStack().pop();
226 break;
227 }
228
229 case UNRESOLVED: {
230 linkTopOfStackReferenceUpdateStack();
231
232 if (resolvable.getResolvableStatus() == UNRESOLVED) {
233 // If current entity is still not resolved, then
234 // linking/resolution has failed.
235 String errorInfo;
236 if (resolvable instanceof YangType) {
237 errorInfo = TYPEDEF_LINKER_ERROR;
238 } else if (resolvable instanceof YangUses) {
239 errorInfo = GROUPING_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +0530240 } else if (resolvable instanceof YangIfFeature) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530241 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530242 } else if (resolvable instanceof YangBase) {
243 errorInfo = BASE_LINKER_ERROR;
244 } else if (resolvable instanceof YangIdentityRef) {
245 errorInfo = IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +0530246 } else {
247 errorInfo = LEAFREF_LINKER_ERROR;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530248 }
249 DataModelException dataModelException =
250 new DataModelException(errorInfo);
251 dataModelException.setLine(getLineNumber());
252 dataModelException.setCharPosition(getCharPosition());
253 throw dataModelException;
254 }
255 break;
256 }
257 default: {
258 throw new DataModelException("Data Model Exception: Unsupported, linker state");
259 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530260
261 }
262
263 } else {
janani be18b5342016-07-13 21:06:41 +0530264 throw new DataModelException(
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530265 "Data Model Exception: Entity to resolved is other than type/uses/if-feature" +
266 "/leafref/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530267 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530268 }
269
270 }
271
272 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530273 * Adds the leafref/identityref type to the type, which has derived type referring to
274 * typedef with leafref/identityref type.
janani be18b5342016-07-13 21:06:41 +0530275 */
276 private void addDerivedRefTypeToRefTypeResolutionList() throws DataModelException {
277
278 YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
279
280 // If holder is typedef return.
281 if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
282 return;
283 }
284
285 // If entity is not type return.
286 if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
287 return;
288 }
289
290 YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
291
292 // If type is not resolved return.
293 if (yangType.getResolvableStatus() != RESOLVED) {
294 return;
295 }
296
297 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
298
299 /*
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530300 * If the derived types referred type is not leafref/identityref return
janani be18b5342016-07-13 21:06:41 +0530301 */
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530302 if ((derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) &&
303 (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.IDENTITYREF)) {
janani be18b5342016-07-13 21:06:41 +0530304 return;
305 }
306
307 T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
308
309 while (extendedInfo instanceof YangDerivedInfo) {
310 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
311 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
312 .getDataTypeExtendedInfo();
313 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530314
janani be18b5342016-07-13 21:06:41 +0530315 /*
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530316 * Backup the derived types leafref/identityref info, delete all the info in current type,
317 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
318 * create a leafref/identityref resolution info using the current resolution info and
319 * add to leafref/identityref resolution list.
janani be18b5342016-07-13 21:06:41 +0530320 */
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530321 if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
322 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
323 yangType.resetYangType();
janani be18b5342016-07-13 21:06:41 +0530324
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530325 yangType.setResolvableStatus(RESOLVED);
326 yangType.setDataType(YangDataTypes.LEAFREF);
327 yangType.setDataTypeName(LEAFREF);
328 yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
329 leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
janani be18b5342016-07-13 21:06:41 +0530330
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530331 // Add resolution information to the list.
332 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
333 potentialAncestorWithReferredNode,
334 getLineNumber(), getCharPosition());
335 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
336 ResolvableType.YANG_LEAFREF);
337 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
338
339 } else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
340
341 YangIdentityRef identityRefInTypeDef = (YangIdentityRef) extendedInfo;
342 yangType.resetYangType();
343
344 yangType.setResolvableStatus(RESOLVED);
345 yangType.setDataType(YangDataTypes.IDENTITYREF);
346 yangType.setDataTypeName(IDENTITYREF);
347 yangType.setDataTypeExtendedInfo(identityRefInTypeDef);
348 identityRefInTypeDef.setResolvableStatus(UNRESOLVED);
349
350 // Add resolution information to the list.
351 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
352 potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
353 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
354 ResolvableType.YANG_IDENTITYREF);
355 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
356 }
janani be18b5342016-07-13 21:06:41 +0530357 }
358
359 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530360 * Resolves the current entity in the stack.
361 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530362 private void resolveTopOfStack(YangLinkingPhase linkingPhase)
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530363 throws DataModelException {
364 ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530365 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
366 && ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
janani be18b5342016-07-13 21:06:41 +0530367 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530368 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
369 }
370 }
371
372 /**
373 * Resolves linking for a node child and siblings.
374 *
375 * @throws DataModelException data model error
376 */
377 private void linkTopOfStackReferenceUpdateStack()
378 throws DataModelException {
379
380 /*
381 * Check if self file reference is there, this will not check for the
382 * scenario when prefix is not present and type/uses is present in
383 * sub-module from include list.
384 */
385 if (!isCandidateForSelfFileReference()) {
386 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
387 return;
388 }
389
390 /**
391 * Try to resolve the top of the stack and update partial resolved stack
392 * if there is recursive references
393 */
394 YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
395 .getHolderOfEntityToResolve();
396
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530397 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
398 resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
399 return;
janani be18b5342016-07-13 21:06:41 +0530400 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
401 resolveSelfFileLinkingForLeafref(potentialAncestorWithReferredNode);
402 return;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530403 } else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
404 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
405 resolveSelfFileLinkingForBaseAndIdentityref();
406 return;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530407 } else {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530408
409 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530410 * Traverse up in the ancestor tree to check if the referred node is
411 * defined
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530412 */
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530413 while (potentialAncestorWithReferredNode != null) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530414
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530415 /**
416 * Check for the referred node defined in a ancestor scope
417 */
418 YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
419 if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
420 return;
421 }
422
423 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
424 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530425 }
426
427 /*
428 * In case prefix is not present it's a candidate for inter-file
429 * resolution via include list.
430 */
431 if (getRefPrefix() == null) {
432 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
433 }
434 }
435
436 /**
janani be18b5342016-07-13 21:06:41 +0530437 * Resolves self file linking for leafref.
438 *
439 * @param potentialAncestorWithReferredNode leafref holder node
440 * @throws DataModelException a violation of data model rules
441 */
442 private void resolveSelfFileLinkingForLeafref(YangNode potentialAncestorWithReferredNode)
443 throws DataModelException {
444
445 YangNode ancestorWithTheReferredNode = potentialAncestorWithReferredNode;
446 YangLeafRef leafref = (YangLeafRef) getCurrentEntityToResolveFromStack();
447 boolean referredLeafFound = false;
448
449 /*
450 * Takes absolute path and takes the root node as module/sub-module,
451 * then sends the list of nodes for finding the target leaf.
452 */
453 if (leafref.getPathType() == YangPathArgType.ABSOLUTE_PATH) {
454 List<YangAtomicPath> atomicPathList = leafref.getAtomicPath();
455 if (atomicPathList != null && !atomicPathList.isEmpty()) {
456 Iterator<YangAtomicPath> listOfYangAtomicPath = atomicPathList.listIterator();
457 if (getCurReferenceResolver() instanceof YangModule) {
458 YangModule rootNode = (YangModule) getCurReferenceResolver();
459 // Sends list of nodes for finding the target leaf.
460 referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
461 referredLeafFound, potentialAncestorWithReferredNode);
462 } else if (getCurReferenceResolver() instanceof YangSubModule) {
463 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
464 // Sends list of nodes for finding the target leaf.
465 referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
466 referredLeafFound, potentialAncestorWithReferredNode);
467 }
468 }
469 /*
470 * Takes relative path, goes to the parent node by using the
471 * ancestor count and sends the list of nodes for finding the target
472 * leaf.
473 */
474 } else if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
475 YangRelativePath yangRelativePath = leafref.getRelativePath();
476 int parentNodes = yangRelativePath.getAncestorNodeCount();
477 List<YangAtomicPath> atomicPathList = yangRelativePath.getAtomicPathList();
478 if (atomicPathList != null && !atomicPathList.isEmpty()) {
479 Iterator<YangAtomicPath> listOfAtomicPath = atomicPathList.listIterator();
480 // Gets the root node from ancestor count.
481 YangNode rootparentNode = getRootNodeWithAncestorCount(parentNodes, ancestorWithTheReferredNode);
482 // Sends list of nodes for finding the target leaf.
483 referredLeafFound = isLeafReferenceFound(listOfAtomicPath, rootparentNode,
484 referredLeafFound, potentialAncestorWithReferredNode);
485 }
486 }
487 if (referredLeafFound) {
488 return;
489 }
490 /*
491 * In case prefix is not present it's a candidate for inter-file
492 * resolution via include list.
493 */
494 if (getRefPrefix() == null) {
495 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
496 }
497 }
498
499 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530500 * Resolves self file linking for base/identityref.
501 *
502 * @throws DataModelException a violation of data model rules
503 */
504 private void resolveSelfFileLinkingForBaseAndIdentityref()
505 throws DataModelException {
506
507 boolean referredIdentityFound = false;
508 String nodeName = null;
509
510 if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
511 nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
512 }
513
514 if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
515 nodeName = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName();
516 }
517
518 if (getCurReferenceResolver() instanceof YangModule) {
519 YangModule rootNode = (YangModule) getCurReferenceResolver();
520 // Sends list of nodes for finding the target identity.
521 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
522 } else if (getCurReferenceResolver() instanceof YangSubModule) {
523 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
524 // Sends list of nodes for finding the target identity.
525 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
526 }
527
528 if (referredIdentityFound) {
529 return;
530 }
531
532 /*
533 * In case prefix is not present it's a candidate for inter-file resolution via include list.
534 */
535 if (getRefPrefix() == null) {
536 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
537 }
538 }
539
540 /**
janani be18b5342016-07-13 21:06:41 +0530541 * Returns the root parent with respect to the ancestor count from leafref.
542 *
543 * @param ancestorCount count of node where parent node can be reached
544 * @param currentParent current parent node
545 * @return root node
546 * @throws DataModelException a violation of data model rules
547 */
548 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
549 throws DataModelException {
550
551 int currentParentCount = 1;
552 while (currentParentCount < ancestorCount) {
553 if (currentParent.getParent() == null) {
554 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
555 }
556 currentParent = currentParent.getParent();
557 currentParentCount = currentParentCount + 1;
558 }
559 return currentParent;
560 }
561
562 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530563 * Resolves self file linking for if-feature.
564 *
565 * @param potentialAncestorWithReferredNode if-feature holder node
566 * @throws DataModelException DataModelException a violation of data model
567 * rules
568 */
569 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
570 throws DataModelException {
571
572 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
573 YangNode potentialReferredNode = (YangNode) featureHolder;
574 if (isReferredNode(potentialReferredNode)) {
575
576 // Adds reference link of entity to the node under resolution.
577 addReferredEntityLink(potentialReferredNode, LINKED);
578
579 /**
580 * resolve the reference and update the partial resolution stack
581 * with any further recursive references
582 */
583 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
584 return;
585 }
586
587 /*
588 * In case prefix is not present it's a candidate for inter-file
589 * resolution via include list.
590 */
591 if (getRefPrefix() == null) {
592 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
593 }
594 }
595
janani be18b5342016-07-13 21:06:41 +0530596 /**
597 * Returns the status of the referred leaf/leaf-list found for leafref.
598 *
599 * @param listOfYangAtomicPath list of atomic paths
600 * @param ancestorWithTheReferredNode the parent node of leafref
601 * @param referredLeafFound status of referred leaf/leaf-list
602 * @param potentialAncestorWithReferredNode holder of the leafref leaf
603 * @return status of referred leaf
604 * @throws DataModelException a violation of data model rules
605 */
606 private boolean isLeafReferenceFound(Iterator<YangAtomicPath> listOfYangAtomicPath,
607 YangNode ancestorWithTheReferredNode, boolean referredLeafFound, YangNode potentialAncestorWithReferredNode)
608 throws DataModelException {
609
610 while (listOfYangAtomicPath.hasNext()) {
611 YangAtomicPath atomicPath = listOfYangAtomicPath.next();
612 String nodeName = atomicPath.getNodeIdentifier().getName();
613
614 // When child is not present, only leaf/leaf-list is available in the node.
615 if (ancestorWithTheReferredNode.getChild() == null) {
616 referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode, nodeName, (T) LINKED);
617 break;
618 }
619 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
620
621 // Checks all the siblings under the node and returns the matched node.
622 YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(ancestorWithTheReferredNode, nodeName);
623
624 // When node is not found in all the siblings, leaf-list may be the node we have to find.
625 if (nodeFound == null) {
626 referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode.getParent(), nodeName,
627 (T) LINKED);
628 } else {
629 ancestorWithTheReferredNode = nodeFound;
630
631 // For the node check if path predicate is present and fill its values.
632 List<YangPathPredicate> pathPredicateList = atomicPath.getPathPredicatesList();
633 if (pathPredicateList != null && !pathPredicateList.isEmpty()) {
634 Iterator<YangPathPredicate> listOfYangPathPredicate = pathPredicateList.listIterator();
635 fillPathPredicatesForTheNode(ancestorWithTheReferredNode, listOfYangPathPredicate,
636 potentialAncestorWithReferredNode);
637 }
638 }
639
640 // If leaf is also not found and node is also not found return the status as false.
641 if (!referredLeafFound && nodeFound == null) {
642 break;
643 }
644 }
645 return referredLeafFound;
646 }
647
648 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530649 * Returns the status of the referred identity found for base/identityref.
650 *
651 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
652 * @param ancestorWithTheReferredNode the parent node of base/identityref
653 * @return status of referred base/identityref
654 * @throws DataModelException a violation of data model rules
655 */
656 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
657 throws DataModelException {
658
659 // When child is not present return.
660 if (ancestorWithTheReferredNode.getChild() == null) {
661 return false;
662 }
663
664 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
665
666 // Checks all the siblings under the node and returns the matched node.
667 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
668
669 if (nodeFound != null) {
670 // Adds reference link of entity to the node under resolution.
671 addReferredEntityLink(nodeFound, LINKED);
672
673 /**
674 * resolve the reference and update the partial resolution stack with any further recursive references
675 */
676 addUnresolvedRecursiveReferenceToStack(nodeFound);
677 return true;
678 }
679
680 return false;
681 }
682
683 /**
janani be18b5342016-07-13 21:06:41 +0530684 * Fills the referred leaf or leaf-list inside the path predicates.
685 *
686 * @param ancestorWithTheReferredNode the actual node where YANG list will be present
687 * @param listOfYangPathPredicate the path predicates present for the node
688 * @param potentialAncestorWithReferredNode the current leaf node parent
689 * @throws DataModelException a violation of data model rules
690 */
691 private void fillPathPredicatesForTheNode(YangNode ancestorWithTheReferredNode,
692 Iterator<YangPathPredicate> listOfYangPathPredicate, YangNode potentialAncestorWithReferredNode)
693 throws DataModelException {
694
695 while (listOfYangPathPredicate.hasNext()) {
696 if (!(ancestorWithTheReferredNode instanceof YangList)) {
697 throw new DataModelException("YANG file error: The path predicates are applicable only for list");
698 }
699 YangPathPredicate pathPredicate = listOfYangPathPredicate.next();
700 YangNodeIdentifier leftNode = pathPredicate.getNodeIdentifier();
701 YangRelativePath relativePath = pathPredicate.getRightRelativePath();
702
703 // Checks that the left axis is filled in the path predicate.
704 boolean isLeftLeafOrLeafListSetForLeftAxis = getLeftLeafOrLeafListInPredicate(
705 (YangList) ancestorWithTheReferredNode, pathPredicate, leftNode);
706 if (!isLeftLeafOrLeafListSetForLeftAxis) {
707 throw new DataModelException(
708 "YANG file error: The path predicate is not referring to an existing leaf/leaflist");
709 }
710 int parentNodes = relativePath.getAncestorNodeCount();
711
712 // Finds the root node for the right relative path.
713 YangNode rootParentNode = getRootNodeWithAncestorCount(parentNodes, potentialAncestorWithReferredNode);
714
715 // Finds the leaf/leaf-list from the right side relative path.
716 resolveRightAxisNodeInPathPredicate(relativePath, rootParentNode, pathPredicate);
717 }
718 }
719
720 /**
721 * Resolves the right axis node in the path predicate.
722 *
723 * @param relativePath the relative path in the path predicate
724 * @param rootParentNode parent node from where the node has to be found
725 * @param pathPredicate data tree reference in YANG list
726 * @throws DataModelException a violation of data model rules
727 */
728 private void resolveRightAxisNodeInPathPredicate(YangRelativePath relativePath, YangNode rootParentNode,
729 YangPathPredicate pathPredicate) throws DataModelException {
730
731 List<YangAtomicPath> absolutePathList = relativePath.getAtomicPathList();
732 if (absolutePathList != null && !absolutePathList.isEmpty()) {
733 Iterator<YangAtomicPath> listOfYangAtomicPathForRightRelative = absolutePathList.listIterator();
734 while (listOfYangAtomicPathForRightRelative.hasNext()) {
735 boolean isRightAxisNodeFound = false;
736 YangAtomicPath absolutePathInPredicate = listOfYangAtomicPathForRightRelative.next();
737 String nodeNameInAtomicPath = absolutePathInPredicate.getNodeIdentifier().getName();
738
739 // When child is not there check the leaf/leaf-list.
740 if (rootParentNode.getChild() == null) {
741 isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode,
742 nodeNameInAtomicPath, (T) pathPredicate);
743 if (!isRightAxisNodeFound) {
744 throw new DataModelException(
745 "YANG file error: The path predicates is not referring to an existing leaf/leaflist");
746 }
747 break;
748 }
749 rootParentNode = rootParentNode.getChild();
750 YangNode nodeFoundInTheRelativePath = isReferredNodeInSiblingProcessedForLeafref(
751 rootParentNode, nodeNameInAtomicPath);
752
753 if (nodeFoundInTheRelativePath == null) {
754
755 // When node is not found check the leaf/leaf-list.
756 isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode.getParent(),
757 nodeNameInAtomicPath, (T) pathPredicate);
758 } else {
759 rootParentNode = nodeFoundInTheRelativePath;
760 }
761 if (!isRightAxisNodeFound && nodeFoundInTheRelativePath == null) {
762 throw new DataModelException(
763 "YANG file error: The path predicates is not referring to an existing leaf/leaflist");
764 }
765 }
766 }
767 }
768
769 /**
770 * Returns the status, if referred leaf/leaf-list is found.
771 *
772 * @param ancestorWithTheReferredNode the parent node of leaf/leaf-list
773 * @param nodeName the name of the leaf/leaf-list
774 * @param statusOrPathPredicate the status to be set for the leaf-ref or the path predicate
775 * @return status of the target node is found
776 * @throws DataModelException a violation of data model rules
777 */
778 private boolean isReferredLeafOrLeafListFound(YangNode ancestorWithTheReferredNode, String nodeName,
779 T statusOrPathPredicate) throws DataModelException {
780
781 if (!(ancestorWithTheReferredNode instanceof YangLeavesHolder)) {
782 throw new DataModelException("Yang file error: The target node of leafref is invalid.");
783 }
784 YangLeavesHolder leavesHolder = (YangLeavesHolder) ancestorWithTheReferredNode;
785 if (leavesHolder.getListOfLeaf() != null) {
786 Iterator<YangLeaf> yangLeavesList = leavesHolder.getListOfLeaf().listIterator();
787 while (yangLeavesList.hasNext()) {
788 YangLeaf yangleaf = yangLeavesList.next();
789 if (yangleaf.getName().contentEquals(nodeName)) {
790 if (statusOrPathPredicate instanceof ResolvableStatus) {
791 ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
792
793 // Sets the referred leaf to YANG leafref.
794 ((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangleaf);
795
796 // Adds reference link of entity to the node under resolution.
797 addReferredEntityLink(ancestorWithTheReferredNode, status);
798 addUnResolvedLeafRefTypeToStack((T) yangleaf, ancestorWithTheReferredNode);
799 return true;
800 } else if (statusOrPathPredicate instanceof YangPathPredicate) {
801 YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
802
803 // Sets the right axis node.
804 pathPredicate.setRightAxisNode(yangleaf);
805 return true;
806 } else {
807 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
808 }
809 }
810 }
811 }
812 if (leavesHolder.getListOfLeafList() != null) {
813 Iterator<YangLeafList> yangLeafListList = leavesHolder.getListOfLeafList().listIterator();
814 while (yangLeafListList.hasNext()) {
815 YangLeafList yangLeaflist = yangLeafListList.next();
816 if (yangLeaflist.getName().contentEquals(nodeName)) {
817 if (statusOrPathPredicate instanceof ResolvableStatus) {
818 ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
819
820 // Sets the referred leaf-list to YANG leafref.
821 ((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangLeaflist);
822
823 // Adds reference link of entity to the node under resolution.
824 addReferredEntityLink(ancestorWithTheReferredNode, status);
825 addUnResolvedLeafRefTypeToStack((T) yangLeaflist, ancestorWithTheReferredNode);
826 return true;
827 } else if (statusOrPathPredicate instanceof YangPathPredicate) {
828 YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
829 pathPredicate.setRightAxisNode(yangLeaflist);
830 return true;
831 } else {
832 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
833 }
834 }
835 }
836 }
837 return false;
838 }
839
840 /**
841 * Adds the unresolved constructs to stack which has to be resolved for leafref.
842 *
843 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
844 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
845 */
846 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
847
848 YangType referredTypeInLeafOrLeafList;
849 if (yangleafOrLeafList instanceof YangLeaf) {
850 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
851 referredTypeInLeafOrLeafList = leaf.getDataType();
852 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
853 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
854 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
855 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
856 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
857 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
858 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
859 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
860 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
861 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
862 }
863 } else {
864 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
865 referredTypeInLeafOrLeafList = leafList.getDataType();
866 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
867 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
868 unResolvedEntityInfo
869 .setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
870 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
871 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
872 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
873 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
874 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
875 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
876 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
877 }
878 }
879 }
880
881 /**
882 * Returns true if referred leaf/leaf-list is found in a particular node. This is for path in path predicate.
883 *
884 * @param listForLeaf list node where referred leaf is found
885 * @param pathPredicate path predicate instance where the value of nodes to be found are available
886 * @param leftNode node identifier of the left side parameter in path predicate
887 * @return status of the leaf/leaf-list found
888 */
889 private boolean getLeftLeafOrLeafListInPredicate(YangList listForLeaf, YangPathPredicate pathPredicate,
890 YangNodeIdentifier leftNode) {
891
892 if (listForLeaf.getListOfLeaf() != null) {
893 Iterator<YangLeaf> yangLeavesUnderList = listForLeaf.getListOfLeaf().listIterator();
894 while (yangLeavesUnderList.hasNext()) {
895 YangLeaf yangleafUnderList = yangLeavesUnderList.next();
896 if (yangleafUnderList.getName().contentEquals(leftNode.getName())) {
897 pathPredicate.setLeftAxisNode(yangleafUnderList);
898 return true;
899 }
900 }
901 }
902 if (listForLeaf.getListOfLeafList() != null) {
903 Iterator<YangLeafList> yangLeavesListUnderList = listForLeaf.getListOfLeafList().listIterator();
904 while (yangLeavesListUnderList.hasNext()) {
905 YangLeafList yangleafListUnderList = yangLeavesListUnderList.next();
906 if (yangleafListUnderList.getName().contentEquals(leftNode.getName())) {
907 pathPredicate.setLeftAxisNode(yangleafListUnderList);
908 return true;
909 }
910 }
911 }
912 return false;
913 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530914
915 /**
916 * Returns feature holder(module/sub-module node) .
917 *
918 * @param potentialAncestorWithReferredNode if-feature holder node
919 */
920 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
921 while (potentialAncestorWithReferredNode != null) {
922 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
923 return (YangFeatureHolder) potentialAncestorWithReferredNode;
924 }
925 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
926 }
927 return null;
928 }
929
930 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530931 * Checks if the reference in self file or in external file.
932 *
933 * @return true if self file reference, false otherwise
934 * @throws DataModelException a violation of data model rules
935 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530936 private boolean isCandidateForSelfFileReference()
937 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530938 String prefix = getRefPrefix();
939 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
940 }
941
942 /**
janani be18b5342016-07-13 21:06:41 +0530943 * Checks for the referred parent node for the leafref path.
944 *
945 * @param potentialReferredNode potential referred node
946 * @return the reffered parent node of leaf/leaf-list
947 * @throws DataModelException data model errors
948 */
949 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
950 throws DataModelException {
951
952 while (potentialReferredNode != null) {
953 if (potentialReferredNode instanceof YangInput) {
954 if (referredNodeName.equalsIgnoreCase(INPUT)) {
955 return potentialReferredNode;
956 }
957 } else if (potentialReferredNode instanceof YangOutput) {
958 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
959 return potentialReferredNode;
960 }
961 }
962 // Check if the potential referred node is the actual referred node
963 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
964 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
965 if (potentialReferredNode.getParent() instanceof YangRpc) {
966 potentialReferredNode = potentialReferredNode.getNextSibling();
967 } else {
968 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
969 }
970 }
971 return potentialReferredNode;
972 }
973 potentialReferredNode = potentialReferredNode.getNextSibling();
974 }
975 return null;
976 }
977
978 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530979 * Checks for the referred parent node for the base/identity.
980 *
981 * @param potentialReferredNode potential referred node
982 * @return the reffered parent node of base/identity.
983 * @throws DataModelException data model errors
984 */
985 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
986 String referredNodeName) throws DataModelException {
987
988 while (potentialReferredNode != null) {
989 if (potentialReferredNode instanceof YangIdentity) {
990 // Check if the potential referred node is the actual referred node
991 if (isReferredNodeForIdentity(potentialReferredNode, referredNodeName)) {
992 return potentialReferredNode;
993 }
994 }
995 potentialReferredNode = potentialReferredNode.getNextSibling();
996 }
997 return null;
998 }
999
1000 /**
janani be18b5342016-07-13 21:06:41 +05301001 * Checks if the current reference node name and the name in the path are equal.
1002 *
1003 * @param currentReferredNode the node where the reference is pointed
1004 * @param nameOfNodeinPath name of the node in the path
1005 * @return status of the match between the name
1006 * @throws DataModelException a violation of data model rules
1007 */
1008 private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
1009 throws DataModelException {
1010
1011 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1012 /*
1013 * Check if name of node name matches with the current reference
1014 * node.
1015 */
1016 return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
1017 } else {
1018 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
1019 }
1020 }
1021
1022 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301023 * Checks if the current reference node name and the name in the base/identityref base are equal.
1024 *
1025 * @param currentReferredNode the node where the reference is pointed
1026 * @param nameOfIdentityRefBase name of the base in the base/identityref base
1027 * @return status of the match between the name
1028 * @throws DataModelException a violation of data model rules
1029 */
1030 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
1031 throws DataModelException {
1032
1033 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
1034 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
1035 /*
1036 * Check if name of node name matches with the current reference node.
1037 */
1038 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
1039 } else {
1040 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref");
1041 }
1042 }
1043
1044 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301045 * Checks for the referred node defined in a ancestor scope.
1046 *
1047 * @param potentialReferredNode potential referred node
1048 * @return status of resolution and updating the partial resolved stack with
1049 * the any recursive references
janani be18b5342016-07-13 21:06:41 +05301050 * @throws DataModelException a violation of data model rules
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301051 */
1052 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
1053 throws DataModelException {
1054 while (potentialReferredNode != null) {
1055
1056 // Check if the potential referred node is the actual referred node
1057 if (isReferredNode(potentialReferredNode)) {
1058
1059 // Adds reference link of entity to the node under resolution.
1060 addReferredEntityLink(potentialReferredNode, LINKED);
1061
1062 /**
1063 * resolve the reference and update the partial resolution stack
1064 * with any further recursive references
1065 */
1066 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
1067
1068 /*
1069 * return true, since the reference is linked and any recursive
1070 * unresolved references is added to the stack
1071 */
1072 return true;
1073 }
1074
1075 potentialReferredNode = potentialReferredNode.getNextSibling();
1076 }
1077 return false;
1078 }
1079
1080 /**
1081 * Checks if the potential referred node is the actual referred node.
1082 *
1083 * @param potentialReferredNode typedef/grouping node
1084 * @return true if node is of resolve type otherwise false
1085 * @throws DataModelException a violation of data model rules
1086 */
1087 private boolean isReferredNode(YangNode potentialReferredNode)
1088 throws DataModelException {
1089 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1090 if (potentialReferredNode instanceof YangTypeDef) {
1091 /*
1092 * Check if name of node name matches with the entity being
1093 * resolved
1094 */
1095 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1096 }
1097 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1098 if (potentialReferredNode instanceof YangGrouping) {
1099 /*
1100 * Check if name of node name matches with the entity being
1101 * resolved
1102 */
1103 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1104 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301105 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1106 if (potentialReferredNode instanceof YangFeatureHolder) {
1107 /*
1108 * Check if name of node name matches with the entity being
1109 * resolved
1110 */
1111 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1112 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301113 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1114 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
1115 if (potentialReferredNode instanceof YangIdentity) {
1116 /*
1117 * Check if name of node name matches with the entity being
1118 * resolved
1119 */
1120 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1121 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301122 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301123 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
1124 "uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301125 }
1126 return false;
1127 }
1128
1129 /**
1130 * Checks if node name is same as name in resolution info, i.e. name of
1131 * typedef/grouping is same as name of type/uses.
1132 *
1133 * @param node typedef/grouping node
1134 * @return true if node name is same as name in resolution info, otherwise
1135 * false
1136 * @throws DataModelException a violation of data model rules
1137 */
1138
1139 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
1140 throws DataModelException {
1141 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1142 if (node.getName().contentEquals(
1143 ((YangType<?>) getCurrentEntityToResolveFromStack())
1144 .getDataTypeName())) {
1145 return true;
1146 }
1147 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1148 if (node.getName().contentEquals(
1149 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1150 return true;
1151 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301152 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1153 return isFeatureDefinedInNode(node);
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301154 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1155 if (node.getName().contentEquals(
1156 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1157 return true;
1158 }
1159 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1160 if (node.getName().contentEquals(
1161 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
1162 return true;
1163 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301164 } else {
1165 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1166 }
1167 return false;
1168 }
1169
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301170 private boolean isFeatureDefinedInNode(YangNode node) throws DataModelException {
1171 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1172 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
1173 if (featureList != null && !featureList.isEmpty()) {
1174 Iterator<YangFeature> iterator = featureList.iterator();
1175 while (iterator.hasNext()) {
1176 YangFeature feature = iterator.next();
1177 if (ifFeature.getName().equals(feature.getName())) {
1178 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1179 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
1180 return true;
1181 }
1182 }
1183 }
1184 return false;
1185 }
1186
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301187 /**
1188 * Adds reference of grouping/typedef in uses/type.
1189 *
1190 * @param referredNode grouping/typedef node being referred
1191 * @param linkedStatus linked status if success.
1192 * @throws DataModelException a violation of data model rules
1193 */
1194 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
1195 throws DataModelException {
1196 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswal96dfef02016-06-16 00:29:12 +05301197 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1198 .getDataTypeExtendedInfo();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301199 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
1200 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1201 ((YangUses) getCurrentEntityToResolveFromStack())
1202 .setRefGroup((YangGrouping) referredNode);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301203 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1204 // do nothing , referred node is already set
janani be18b5342016-07-13 21:06:41 +05301205 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1206 // do nothing , referred node is already set
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301207 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1208 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
1209 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1210 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301211 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301212 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
1213 "/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301214 }
1215
1216 // Sets the resolution status in inside the type/uses.
1217 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
1218 }
1219
1220 /**
1221 * Checks if type/grouping has further reference to typedef/ unresolved
1222 * uses. Add it to the partial resolve stack and return the status of
1223 * addition to stack.
1224 *
1225 * @param referredNode grouping/typedef node
1226 * @throws DataModelException a violation of data model rules
1227 */
1228 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
1229 throws DataModelException {
1230 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1231 /*
1232 * Checks if typedef type is derived
1233 */
Bharat saraswal96dfef02016-06-16 00:29:12 +05301234 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301235
Bharat saraswal96dfef02016-06-16 00:29:12 +05301236 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301237 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
1238 .getTypeDefBaseType());
1239 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301240 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301241 }
1242
1243 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1244 /*
1245 * Search if the grouping has any un resolved uses child, if so
1246 * return true, else return false.
1247 */
1248 addUnResolvedUsesToStack(referredNode);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301249 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1250 addUnResolvedIfFeatureToStack(referredNode);
janani be18b5342016-07-13 21:06:41 +05301251 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1252 // do nothing , referred node is already set
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301253 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301254 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1255 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
1256 /*
1257 * Search if the identity has any un resolved base, if so return true, else return false.
1258 */
1259 addUnResolvedBaseToStack(referredNode);
1260 } else {
1261 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
1262 "base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301263 }
1264 }
1265
1266 /**
1267 * Returns if there is any unresolved uses in grouping.
1268 *
1269 * @param node grouping/typedef node
1270 */
1271 private void addUnResolvedUsesToStack(YangNode node) {
1272
1273 /**
1274 * Search the grouping node's children for presence of uses node.
1275 */
1276 YangNode curNode = node.getChild();
1277 while (curNode != null) {
1278 if (curNode instanceof YangUses) {
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301279 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301280 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1281 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301282 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301283
1284 }
1285 curNode = curNode.getNextSibling();
1286 }
1287 }
1288
1289 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301290 * Returns if there is any unresolved if-feature in feature.
1291 *
1292 * @param node module/submodule node
1293 */
1294 private void addUnResolvedIfFeatureToStack(YangNode node) {
1295 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1296 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1297 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1298 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1299 while (ifFeatureIterator.hasNext()) {
1300 YangIfFeature ifFeature = ifFeatureIterator.next();
1301 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1302 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1303 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1304 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1305 }
1306 }
1307 }
1308
1309 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301310 * Returns if there is any unresolved base in identity.
1311 *
1312 * @param node module/submodule node
1313 */
1314 private void addUnResolvedBaseToStack(YangNode node) {
1315
1316 YangIdentity curNode = (YangIdentity) node;
1317 if (curNode.getBaseNode() != null) {
1318 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1319 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1320 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1321 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1322 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1323
1324 }
1325 }
1326 }
1327
1328
1329 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301330 * Returns stack of YANG type with partially resolved YANG construct
1331 * hierarchy.
1332 *
1333 * @return partial resolved YANG construct stack
1334 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301335 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301336 return partialResolvedStack;
1337 }
1338
1339 /**
1340 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1341 *
1342 * @param partialResolvedStack partial resolved YANG construct stack
1343 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301344 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301345 this.partialResolvedStack = partialResolvedStack;
1346 }
1347
1348 /**
1349 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1350 *
1351 * @param partialResolvedInfo partial resolved YANG construct stack
1352 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301353 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301354 getPartialResolvedStack().push(partialResolvedInfo);
1355 }
1356
1357 /**
1358 * Retrieves the next entity in the stack that needs to be resolved. It is
1359 * assumed that the caller ensures that the stack is not empty.
1360 *
1361 * @return next entity in the stack that needs to be resolved
1362 */
1363 private T getCurrentEntityToResolveFromStack() {
1364 return getPartialResolvedStack().peek().getEntityToResolve();
1365 }
1366
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301367 @Override
1368 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301369 return entityToResolveInfo;
1370 }
1371
1372 /**
1373 * Sets information about the entity that needs to be resolved.
1374 *
1375 * @param entityToResolveInfo information about the entity that needs to be
1376 * resolved
1377 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301378 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301379 this.entityToResolveInfo = entityToResolveInfo;
1380 }
1381
1382 @Override
1383 public int getLineNumber() {
1384 return lineNumber;
1385 }
1386
1387 @Override
1388 public int getCharPosition() {
1389 return charPosition;
1390 }
1391
1392 @Override
1393 public void setLineNumber(int lineNumber) {
1394 this.lineNumber = lineNumber;
1395 }
1396
1397 @Override
1398 public void setCharPosition(int charPositionInLine) {
1399 this.charPosition = charPositionInLine;
1400 }
1401
1402 /**
1403 * Returns current module/sub-module reference, will be used in inter-file/
1404 * inter-jar scenario to get the import/include list.
1405 *
1406 * @return current module/sub-module reference
1407 */
1408 private YangReferenceResolver getCurReferenceResolver() {
1409 return curReferenceResolver;
1410 }
1411
1412 /**
1413 * Sets current module/sub-module reference, will be used in inter-file/
1414 * inter-jar scenario to get the import/include list.
1415 *
1416 * @param curReferenceResolver current module/sub-module reference
1417 */
1418 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1419 this.curReferenceResolver = curReferenceResolver;
1420 }
1421
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301422 @Override
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301423 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1424 throws DataModelException {
1425
1426 setCurReferenceResolver(dataModelRootNode);
1427
1428 // Current node to resolve, it can be a YANG type or YANG uses.
1429 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1430
1431 // Check if linking is already done
1432 if (entityToResolve instanceof Resolvable) {
1433 Resolvable resolvable = (Resolvable) entityToResolve;
1434 if (resolvable.getResolvableStatus() == RESOLVED) {
1435 return;
1436 }
1437 } else {
1438 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1439 }
1440
1441 // Push the initial entity to resolve in stack.
1442 addInPartialResolvedStack(getEntityToResolveInfo());
1443
1444 // Inter file linking and resolution.
1445 linkInterFileAndResolve();
janani be18b5342016-07-13 21:06:41 +05301446
1447 // Resolve the derived types having leafref.
1448 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301449 }
1450
1451 /**
1452 * Returns the referenced prefix of entity under resolution.
1453 *
1454 * @return referenced prefix of entity under resolution
1455 * @throws DataModelException a violation in data model rule
1456 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301457 private String getRefPrefix()
1458 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301459 String refPrefix;
1460 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1461 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1462 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1463 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301464 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1465 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
janani be18b5342016-07-13 21:06:41 +05301466 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1467 refPrefix = refPrefixForLeafRef();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301468 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1469 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1470 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1471 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301472 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301473 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
1474 "type/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301475 }
1476 return refPrefix;
1477 }
1478
1479 /**
janani be18b5342016-07-13 21:06:41 +05301480 * Returns the referenced prefix for leafref under resolution.
1481 *
1482 * @return referenced prefix of leafref under resolution
1483 */
1484 private String refPrefixForLeafRef() {
1485
1486 String refPrefix;
1487 if (((YangLeafRef) getCurrentEntityToResolveFromStack()).getPathType() == YangPathArgType.ABSOLUTE_PATH) {
1488 List<YangAtomicPath> theList = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getAtomicPath();
1489 YangAtomicPath absPath = theList.iterator().next();
1490 refPrefix = absPath.getNodeIdentifier().getPrefix();
1491 } else {
1492 YangRelativePath relativePath = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getRelativePath();
1493 List<YangAtomicPath> theList = relativePath.getAtomicPathList();
1494 YangAtomicPath absPath = theList.iterator().next();
1495 refPrefix = absPath.getNodeIdentifier().getPrefix();
1496 }
1497 return refPrefix;
1498 }
1499
1500 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301501 * Performs inter file linking and resolution.
1502 *
1503 * @throws DataModelException a violation in data model rule
1504 */
1505 private void linkInterFileAndResolve()
1506 throws DataModelException {
1507
1508 while (getPartialResolvedStack().size() != 0) {
1509
1510 // Current node to resolve, it can be a YANG type or YANG uses.
1511 T entityToResolve = getCurrentEntityToResolveFromStack();
1512 // Check if linking is already done
1513 if (entityToResolve instanceof Resolvable) {
1514
1515 Resolvable resolvable = (Resolvable) entityToResolve;
1516 switch (resolvable.getResolvableStatus()) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301517 case RESOLVED: {
1518 /*
1519 * If the entity is already resolved in the stack, then pop
1520 * it and continue with the remaining stack elements to
1521 * resolve
1522 */
1523 getPartialResolvedStack().pop();
1524 break;
1525 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301526
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301527 case INTER_FILE_LINKED: {
1528 /*
1529 * If the top of the stack is already linked then resolve
1530 * the references and pop the entity and continue with
1531 * remaining stack elements to resolve
1532 */
1533 resolveTopOfStack(INTER_FILE);
1534 getPartialResolvedStack().pop();
1535 break;
1536 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301537
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301538 case INTRA_FILE_RESOLVED: {
1539 /*
1540 * If the top of the stack is intra file resolved then check
1541 * if top of stack is linked, if not link it using
1542 * import/include list and push the linked referred entity
1543 * to the stack, otherwise only push it to the stack.
1544 */
1545 linkInterFileTopOfStackRefUpdateStack();
1546 break;
1547 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301548
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301549 case UNDEFINED: {
1550 /*
1551 * In case of if-feature resolution, if referred "feature" is not
1552 * defined then the resolvable status will be undefined.
1553 */
1554 getPartialResolvedStack().pop();
1555 break;
1556 }
1557
1558 default: {
1559 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1560 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301561
1562 }
1563
1564 } else {
1565 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1566 }
1567
1568 }
1569
1570 }
1571
1572 /**
1573 * Links the top of the stack if it's inter-file and update stack.
1574 *
1575 * @throws DataModelException data model error
1576 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301577 private void linkInterFileTopOfStackRefUpdateStack()
1578 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301579
1580 /*
1581 * Obtain the referred node of top of stack entity under resolution
1582 */
1583 T referredNode = getRefNode();
1584
1585 /*
1586 * Check for null for scenario when it's not linked and inter-file
1587 * linking is required.
1588 */
1589 if (referredNode == null) {
1590
1591 /*
Bharat saraswal96dfef02016-06-16 00:29:12 +05301592 * Check if prefix is null or not, to identify whether to search in
1593 * import list or include list.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301594 */
Bharat saraswalcad0e652016-05-26 23:48:38 +05301595 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301596 if (resolveWithImport()) {
1597 return;
1598 }
1599 } else {
1600 if (resolveWithInclude()) {
1601 return;
1602 }
1603 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301604
1605 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1606 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1607 return;
1608 }
janani be18b5342016-07-13 21:06:41 +05301609 // If current entity is still not resolved, then
1610 // linking/resolution has failed.
1611 String errorInfo;
1612 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1613 errorInfo = TYPEDEF_LINKER_ERROR;
1614 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1615 errorInfo = GROUPING_LINKER_ERROR;
1616 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1617 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301618 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1619 errorInfo = BASE_LINKER_ERROR;
1620 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1621 errorInfo = IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +05301622 } else {
1623 errorInfo = LEAFREF_LINKER_ERROR;
1624 }
1625 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301626 dataModelException.setLine(getLineNumber());
1627 dataModelException.setCharPosition(getCharPosition());
1628 throw dataModelException;
1629 } else {
1630 /*
1631 * If referred node is already linked, then just change the status
1632 * and push to the stack.
1633 */
janani be18b5342016-07-13 21:06:41 +05301634 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1635 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1636 if (referredNode instanceof YangLeaf) {
1637 YangLeaf yangleaf = (YangLeaf) referredNode;
1638 addUnResolvedLeafRefTypeToStack((T) yangleaf, (YangNode) yangleaf.getContainedIn());
1639 } else if (referredNode instanceof YangLeafList) {
1640 YangLeafList yangLeafList = (YangLeafList) referredNode;
1641 addUnResolvedLeafRefTypeToStack((T) yangLeafList, (YangNode) yangLeafList.getContainedIn());
1642 }
1643 } else {
1644 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1645 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1646 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301647 }
1648 }
1649
1650 /**
1651 * Finds and resolves with include list.
1652 *
1653 * @return true if resolved, false otherwise
1654 * @throws DataModelException a violation in data model rule
1655 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301656 private boolean resolveWithInclude()
1657 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301658 /*
1659 * Run through all the nodes in include list and search for referred
1660 * typedef/grouping at the root level.
1661 */
1662 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1663 YangNode linkedNode = null;
1664 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1665 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1666 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1667 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301668 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1669 linkedNode = findRefFeature(yangInclude.getIncludedNode());
janani be18b5342016-07-13 21:06:41 +05301670 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1671 boolean referredNode = findRefLeaf(yangInclude.getIncludedNode());
1672 /*
1673 * Update the current reference resolver to external
1674 * module/sub-module containing the referred typedef/grouping.
1675 */
1676 setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
1677
1678 return referredNode;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301679 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1680 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1681 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1682 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301683 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301684
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301685 if (linkedNode != null) {
1686 // Add the link to external entity.
1687 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
1688 /*
1689 * Update the current reference resolver to external
1690 * module/sub-module containing the referred typedef/grouping.
1691 */
1692 setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
1693 // Add the type/uses of referred typedef/grouping to the stack.
1694 addUnresolvedRecursiveReferenceToStack(linkedNode);
1695 return true;
1696 }
1697 }
1698 // If referred node can't be found return false.
1699 return false;
1700 }
1701
1702 /**
1703 * Finds and resolves with import list.
1704 *
1705 * @return true if resolved, false otherwise
1706 * @throws DataModelException a violation in data model rule
1707 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301708 private boolean resolveWithImport()
1709 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301710 /*
1711 * Run through import list to find the referred typedef/grouping.
1712 */
1713 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1714 /*
1715 * Match the prefix attached to entity under resolution with the
1716 * imported/included module/sub-module's prefix. If found, search
1717 * for the referred typedef/grouping at the root level.
1718 */
1719 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1720 YangNode linkedNode = null;
1721 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1722 linkedNode = findRefTypedef(yangImport.getImportedNode());
1723 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1724 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301725 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1726 linkedNode = findRefFeature(yangImport.getImportedNode());
janani be18b5342016-07-13 21:06:41 +05301727 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1728 boolean referredNode = findRefLeaf(yangImport.getImportedNode());
1729 /*
1730 * Update the current reference resolver to external
1731 * module/sub-module containing the referred
1732 * typedef/grouping.
1733 */
1734 setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
1735
1736 return referredNode;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301737 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1738 linkedNode = findRefIdentity(yangImport.getImportedNode());
1739 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1740 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301741 }
1742 if (linkedNode != null) {
1743 // Add the link to external entity.
1744 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
1745 /*
1746 * Update the current reference resolver to external
Bharat saraswal96dfef02016-06-16 00:29:12 +05301747 * module/sub-module containing the referred
1748 * typedef/grouping.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301749 */
1750 setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
Bharat saraswal96dfef02016-06-16 00:29:12 +05301751 // Add the type/uses of referred typedef/grouping to the
1752 // stack.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301753 addUnresolvedRecursiveReferenceToStack(linkedNode);
1754 return true;
1755 }
1756 /*
1757 * If referred node can't be found at root level break for loop,
1758 * and return false.
1759 */
1760 break;
1761 }
1762 }
1763 // If referred node can't be found return false.
1764 return false;
1765 }
1766
1767 /**
janani be18b5342016-07-13 21:06:41 +05301768 * Returns the status of referred leaf.
1769 *
1770 * @param importedNode the root node from a YANG file
1771 * @return status of the referred leaf
1772 * @throws DataModelException
1773 */
1774 private boolean findRefLeaf(YangNode importedNode) throws DataModelException {
1775
1776 boolean isReferredNodeFound = false;
1777 List<YangAtomicPath> absolutePathList = ((YangLeafRef) getCurrentEntityToResolveFromStack())
1778 .getAtomicPath();
1779 if (absolutePathList != null && !absolutePathList.isEmpty()) {
1780 Iterator<YangAtomicPath> listOfYangAtomicPath = absolutePathList.listIterator();
1781
1782 while (listOfYangAtomicPath.hasNext()) {
1783 YangAtomicPath absolutePath = listOfYangAtomicPath.next();
1784 String nodeName = absolutePath.getNodeIdentifier().getName();
1785
1786 if (importedNode.getChild() == null) {
1787 isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode, nodeName, (T) INTER_FILE_LINKED);
1788 break;
1789 }
1790 importedNode = importedNode.getChild();
1791
1792 YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(importedNode, nodeName);
1793 if (nodeFound == null) {
1794 isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode.getParent(), nodeName,
1795 (T) INTER_FILE_LINKED);
1796 } else {
1797 importedNode = nodeFound;
1798 }
1799 }
1800 }
1801 // TODO: Path predicates filling for inter file has to be done.
1802 return isReferredNodeFound;
1803 }
1804
1805 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301806 * Returns referred typedef/grouping node.
1807 *
1808 * @return referred typedef/grouping node
1809 * @throws DataModelException a violation in data model rule
1810 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301811 private T getRefNode()
1812 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301813 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswal96dfef02016-06-16 00:29:12 +05301814 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1815 .getDataTypeExtendedInfo();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301816 return (T) derivedInfo.getReferredTypeDef();
1817 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1818 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301819 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1820 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani be18b5342016-07-13 21:06:41 +05301821 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1822 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301823 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1824 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1825 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1826 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301827 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301828 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
1829 "/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301830 }
1831 }
1832
1833 /**
1834 * Finds the referred grouping node at the root level of imported/included node.
1835 *
1836 * @param refNode module/sub-module node
1837 * @return referred grouping
1838 */
1839 private YangNode findRefGrouping(YangNode refNode) {
1840 YangNode tmpNode = refNode.getChild();
1841 while (tmpNode != null) {
1842 if (tmpNode instanceof YangGrouping) {
1843 if (tmpNode.getName()
1844 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1845 return tmpNode;
1846 }
1847 }
1848 tmpNode = tmpNode.getNextSibling();
1849 }
1850 return null;
1851 }
1852
1853 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301854 * Finds the referred feature node at the root level of imported/included node.
1855 *
1856 * @param refNode module/sub-module node
1857 * @return referred feature
1858 */
1859 private YangNode findRefFeature(YangNode refNode) {
1860 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1861 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1862
1863 if (featureList != null && !featureList.isEmpty()) {
1864 Iterator<YangFeature> iterator = featureList.iterator();
1865 while (iterator.hasNext()) {
1866 YangFeature feature = iterator.next();
1867 if (ifFeature.getName().equals(feature.getName())) {
1868 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1869 return refNode;
1870 }
1871 }
1872 }
1873 return null;
1874 }
1875
1876 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301877 * Finds the referred typedef node at the root level of imported/included node.
1878 *
1879 * @param refNode module/sub-module node
1880 * @return referred typedef
1881 */
1882 private YangNode findRefTypedef(YangNode refNode) {
1883 YangNode tmpNode = refNode.getChild();
1884 while (tmpNode != null) {
1885 if (tmpNode instanceof YangTypeDef) {
1886 if (tmpNode.getName()
1887 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1888 return tmpNode;
1889 }
1890 }
1891 tmpNode = tmpNode.getNextSibling();
1892 }
1893 return null;
1894 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301895
1896 /**
1897 * Finds the referred identity node at the root level of imported/included node.
1898 *
1899 * @param refNode module/sub-module node
1900 * @return referred identity
1901 */
1902 private YangNode findRefIdentity(YangNode refNode) {
1903 YangNode tmpNode = refNode.getChild();
1904 while (tmpNode != null) {
1905 if (tmpNode instanceof YangIdentity) {
1906 if (tmpNode.getName()
1907 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1908 return tmpNode;
1909 }
1910 }
1911 tmpNode = tmpNode.getNextSibling();
1912 }
1913 return null;
1914 }
1915
1916 /**
1917 * Finds the referred identity node at the root level of imported/included node.
1918 *
1919 * @param refNode module/sub-module node
1920 * @return referred identity
1921 */
1922 private YangNode findRefIdentityRef(YangNode refNode) {
1923 YangNode tmpNode = refNode.getChild();
1924 while (tmpNode != null) {
1925 if (tmpNode instanceof YangIdentity) {
1926 if (tmpNode.getName()
1927 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
1928 .getBaseIdentity().getName())) {
1929 return tmpNode;
1930 }
1931 }
1932 tmpNode = tmpNode.getNextSibling();
1933 }
1934 return null;
1935 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301936}