blob: a502dd83406447749a7fac2a688d0ed04802ac28 [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;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053027import org.onosproject.yangutils.datamodel.YangAugment;
28import org.onosproject.yangutils.datamodel.YangAugmentableNode;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053029import org.onosproject.yangutils.datamodel.YangBase;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053030import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053031import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
32import org.onosproject.yangutils.datamodel.YangFeature;
33import org.onosproject.yangutils.datamodel.YangFeatureHolder;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053034import org.onosproject.yangutils.datamodel.YangGrouping;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053035import org.onosproject.yangutils.datamodel.YangIdentity;
36import org.onosproject.yangutils.datamodel.YangIdentityRef;
Bharat saraswalb551aae2016-07-14 15:18:20 +053037import org.onosproject.yangutils.datamodel.YangIfFeature;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053038import org.onosproject.yangutils.datamodel.YangImport;
39import org.onosproject.yangutils.datamodel.YangInclude;
janani be18b5342016-07-13 21:06:41 +053040import org.onosproject.yangutils.datamodel.YangInput;
41import org.onosproject.yangutils.datamodel.YangLeaf;
42import org.onosproject.yangutils.datamodel.YangLeafList;
43import org.onosproject.yangutils.datamodel.YangLeafRef;
44import org.onosproject.yangutils.datamodel.YangLeavesHolder;
45import org.onosproject.yangutils.datamodel.YangList;
46import org.onosproject.yangutils.datamodel.YangModule;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053047import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053048import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
janani be18b5342016-07-13 21:06:41 +053049import org.onosproject.yangutils.datamodel.YangOutput;
50import org.onosproject.yangutils.datamodel.YangPathArgType;
51import org.onosproject.yangutils.datamodel.YangPathPredicate;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053052import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani be18b5342016-07-13 21:06:41 +053053import org.onosproject.yangutils.datamodel.YangRelativePath;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053054import org.onosproject.yangutils.datamodel.YangResolutionInfo;
janani be18b5342016-07-13 21:06:41 +053055import org.onosproject.yangutils.datamodel.YangRpc;
56import org.onosproject.yangutils.datamodel.YangSubModule;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053057import org.onosproject.yangutils.datamodel.YangType;
58import org.onosproject.yangutils.datamodel.YangTypeDef;
59import org.onosproject.yangutils.datamodel.YangUses;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053060import org.onosproject.yangutils.datamodel.YangXPathResolver;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053061import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswal96dfef02016-06-16 00:29:12 +053062import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
janani be18b5342016-07-13 21:06:41 +053063import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +053064import org.onosproject.yangutils.linker.YangLinkingPhase;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053065import org.onosproject.yangutils.linker.exceptions.LinkerException;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053066
Bharat saraswal96dfef02016-06-16 00:29:12 +053067import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
68import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
69import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
70import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053071import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNDEFINED;
Bharat saraswal96dfef02016-06-16 00:29:12 +053072import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +053073import static org.onosproject.yangutils.linker.YangLinkingPhase.INTER_FILE;
74import static org.onosproject.yangutils.linker.YangLinkingPhase.INTRA_FILE;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053075import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
Bharat saraswalb551aae2016-07-14 15:18:20 +053076import static org.onosproject.yangutils.utils.UtilConstants.BASE_LINKER_ERROR;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053077import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
Vidyashree Rama210c01d2016-05-20 16:29:25 +053078import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
Bharat saraswalb551aae2016-07-14 15:18:20 +053079import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
80import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +053081import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
82import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
83import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
84import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053085import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053086
87/**
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053088 * Represents implementation of resolution object which will be resolved by
89 * linker.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053090 *
91 * @param <T> type of resolution entity uses / type
92 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053093public class YangResolutionInfoImpl<T>
Bharat saraswal96dfef02016-06-16 00:29:12 +053094 implements YangResolutionInfo<T>, Serializable {
95
96 private static final long serialVersionUID = 806201658L;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +053097
98 /**
99 * Information about the entity that needs to be resolved.
100 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530101 private YangEntityToResolveInfoImpl<T> entityToResolveInfo;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530102
103 /**
104 * Error line number.
105 */
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530106 private transient int lineNumber;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530107
108 /**
109 * Error character position in number.
110 */
Bharat saraswal96dfef02016-06-16 00:29:12 +0530111 private transient int charPosition;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530112
113 /**
114 * Current module/sub-module reference, will be used in inter-file/
115 * inter-jar scenario to get the import/include list.
116 */
Bharat saraswal96dfef02016-06-16 00:29:12 +0530117 private transient YangReferenceResolver curReferenceResolver;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530118
119 /**
120 * Stack for type/uses is maintained for hierarchical references, this is
121 * used during resolution.
122 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530123 private Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530124
125 /**
126 * It is private to ensure the overloaded method be invoked to create an
127 * object.
128 */
129 @SuppressWarnings("unused")
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530130 private YangResolutionInfoImpl() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530131 }
132
133 /**
134 * Creates a resolution information object with all the inputs.
135 *
136 * @param dataNode current parsable data node
137 * @param holderNode parent YANG node
138 * @param lineNumber error line number
139 * @param charPositionInLine error character position in line
140 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530141 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
142 setEntityToResolveInfo(new YangEntityToResolveInfoImpl<>());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530143 getEntityToResolveInfo().setEntityToResolve(dataNode);
144 getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
145 this.setLineNumber(lineNumber);
146 this.setCharPosition(charPositionInLine);
147 setPartialResolvedStack(new Stack<>());
148 }
149
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530150 @Override
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530151 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
152 throws DataModelException {
153
154 setCurReferenceResolver(dataModelRootNode);
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530155 /**
156 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
157 * YANG leafref or YANG base or YANG identityref.
158 */
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530159 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
160
161 // Check if linking is already done
162 if (entityToResolve instanceof Resolvable) {
163 Resolvable resolvable = (Resolvable) entityToResolve;
164 if (resolvable.getResolvableStatus() == RESOLVED) {
165 /**
166 * entity is already resolved, so nothing to do
167 */
168 return;
169 }
170 } else {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530171 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530172 "type/uses/if-feature/leafref/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530173 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530174 // Push the initial entity to resolve in stack.
175 addInPartialResolvedStack(getEntityToResolveInfo());
176
177 linkAndResolvePartialResolvedStack();
janani be18b5342016-07-13 21:06:41 +0530178
179 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530180 }
181
182 /**
183 * Resolves linking with ancestors.
184 *
185 * @throws DataModelException a violation of data model rules
186 */
187 private void linkAndResolvePartialResolvedStack()
188 throws DataModelException {
189
190 while (getPartialResolvedStack().size() != 0) {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530191 /**
192 * Current node to resolve, it can be a YANG type or YANG uses or
193 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
194 */
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530195 T entityToResolve = getCurrentEntityToResolveFromStack();
196 // Check if linking is already done
197 if (entityToResolve instanceof Resolvable) {
198
199 Resolvable resolvable = (Resolvable) entityToResolve;
200 switch (resolvable.getResolvableStatus()) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530201 case RESOLVED: {
202 /*
203 * If the entity is already resolved in the stack, then pop
204 * it and continue with the remaining stack elements to
205 * resolve
206 */
207 getPartialResolvedStack().pop();
208 break;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530209 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530210
211 case LINKED: {
212 /*
213 * If the top of the stack is already linked then resolve
214 * the references and pop the entity and continue with
215 * remaining stack elements to resolve.
216 */
217 resolveTopOfStack(INTRA_FILE);
218 getPartialResolvedStack().pop();
219 break;
220 }
221
222 case INTRA_FILE_RESOLVED: {
223 /*
224 * Pop the top of the stack.
225 */
226 getPartialResolvedStack().pop();
227 break;
228 }
229
230 case UNRESOLVED: {
231 linkTopOfStackReferenceUpdateStack();
232
233 if (resolvable.getResolvableStatus() == UNRESOLVED) {
234 // If current entity is still not resolved, then
235 // linking/resolution has failed.
236 String errorInfo;
237 if (resolvable instanceof YangType) {
238 errorInfo = TYPEDEF_LINKER_ERROR;
239 } else if (resolvable instanceof YangUses) {
240 errorInfo = GROUPING_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +0530241 } else if (resolvable instanceof YangIfFeature) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530242 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530243 } else if (resolvable instanceof YangBase) {
244 errorInfo = BASE_LINKER_ERROR;
245 } else if (resolvable instanceof YangIdentityRef) {
246 errorInfo = IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +0530247 } else {
248 errorInfo = LEAFREF_LINKER_ERROR;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530249 }
250 DataModelException dataModelException =
251 new DataModelException(errorInfo);
252 dataModelException.setLine(getLineNumber());
253 dataModelException.setCharPosition(getCharPosition());
254 throw dataModelException;
255 }
256 break;
257 }
258 default: {
259 throw new DataModelException("Data Model Exception: Unsupported, linker state");
260 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530261
262 }
263
264 } else {
janani be18b5342016-07-13 21:06:41 +0530265 throw new DataModelException(
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530266 "Data Model Exception: Entity to resolved is other than type/uses/if-feature" +
267 "/leafref/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530268 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530269 }
270
271 }
272
273 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530274 * Adds the leafref/identityref type to the type, which has derived type referring to
275 * typedef with leafref/identityref type.
janani be18b5342016-07-13 21:06:41 +0530276 */
277 private void addDerivedRefTypeToRefTypeResolutionList() throws DataModelException {
278
279 YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
280
281 // If holder is typedef return.
282 if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
283 return;
284 }
285
286 // If entity is not type return.
287 if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
288 return;
289 }
290
291 YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
292
293 // If type is not resolved return.
294 if (yangType.getResolvableStatus() != RESOLVED) {
295 return;
296 }
297
298 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
299
300 /*
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530301 * If the derived types referred type is not leafref/identityref return
janani be18b5342016-07-13 21:06:41 +0530302 */
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530303 if ((derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) &&
304 (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.IDENTITYREF)) {
janani be18b5342016-07-13 21:06:41 +0530305 return;
306 }
307
308 T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
309
310 while (extendedInfo instanceof YangDerivedInfo) {
311 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
312 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
313 .getDataTypeExtendedInfo();
314 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530315
janani be18b5342016-07-13 21:06:41 +0530316 /*
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530317 * Backup the derived types leafref/identityref info, delete all the info in current type,
318 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
319 * create a leafref/identityref resolution info using the current resolution info and
320 * add to leafref/identityref resolution list.
janani be18b5342016-07-13 21:06:41 +0530321 */
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530322 if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
323 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
324 yangType.resetYangType();
janani be18b5342016-07-13 21:06:41 +0530325
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530326 yangType.setResolvableStatus(RESOLVED);
327 yangType.setDataType(YangDataTypes.LEAFREF);
328 yangType.setDataTypeName(LEAFREF);
329 yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
330 leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
janani be18b5342016-07-13 21:06:41 +0530331
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530332 // Add resolution information to the list.
333 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
334 potentialAncestorWithReferredNode,
335 getLineNumber(), getCharPosition());
336 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
337 ResolvableType.YANG_LEAFREF);
338 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
339
340 } else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
341
342 YangIdentityRef identityRefInTypeDef = (YangIdentityRef) extendedInfo;
343 yangType.resetYangType();
344
345 yangType.setResolvableStatus(RESOLVED);
346 yangType.setDataType(YangDataTypes.IDENTITYREF);
347 yangType.setDataTypeName(IDENTITYREF);
348 yangType.setDataTypeExtendedInfo(identityRefInTypeDef);
349 identityRefInTypeDef.setResolvableStatus(UNRESOLVED);
350
351 // Add resolution information to the list.
352 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
353 potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
354 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
355 ResolvableType.YANG_IDENTITYREF);
356 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
357 }
janani be18b5342016-07-13 21:06:41 +0530358 }
359
360 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530361 * Resolves the current entity in the stack.
362 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530363 private void resolveTopOfStack(YangLinkingPhase linkingPhase)
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530364 throws DataModelException {
365 ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530366 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
367 && ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
janani be18b5342016-07-13 21:06:41 +0530368 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530369 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
370 }
371 }
372
373 /**
374 * Resolves linking for a node child and siblings.
375 *
376 * @throws DataModelException data model error
377 */
378 private void linkTopOfStackReferenceUpdateStack()
379 throws DataModelException {
380
381 /*
382 * Check if self file reference is there, this will not check for the
383 * scenario when prefix is not present and type/uses is present in
384 * sub-module from include list.
385 */
386 if (!isCandidateForSelfFileReference()) {
387 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
388 return;
389 }
390
391 /**
392 * Try to resolve the top of the stack and update partial resolved stack
393 * if there is recursive references
394 */
395 YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
396 .getHolderOfEntityToResolve();
397
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530398 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
399 resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
400 return;
janani be18b5342016-07-13 21:06:41 +0530401 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
402 resolveSelfFileLinkingForLeafref(potentialAncestorWithReferredNode);
403 return;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530404 } else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
405 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
406 resolveSelfFileLinkingForBaseAndIdentityref();
407 return;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530408 } else {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530409
410 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530411 * Traverse up in the ancestor tree to check if the referred node is
412 * defined
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530413 */
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530414 while (potentialAncestorWithReferredNode != null) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530415
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530416 /**
417 * Check for the referred node defined in a ancestor scope
418 */
419 YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
420 if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
421 return;
422 }
423
424 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
425 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530426 }
427
428 /*
429 * In case prefix is not present it's a candidate for inter-file
430 * resolution via include list.
431 */
432 if (getRefPrefix() == null) {
433 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
434 }
435 }
436
437 /**
janani be18b5342016-07-13 21:06:41 +0530438 * Resolves self file linking for leafref.
439 *
440 * @param potentialAncestorWithReferredNode leafref holder node
441 * @throws DataModelException a violation of data model rules
442 */
443 private void resolveSelfFileLinkingForLeafref(YangNode potentialAncestorWithReferredNode)
444 throws DataModelException {
445
446 YangNode ancestorWithTheReferredNode = potentialAncestorWithReferredNode;
447 YangLeafRef leafref = (YangLeafRef) getCurrentEntityToResolveFromStack();
448 boolean referredLeafFound = false;
449
450 /*
451 * Takes absolute path and takes the root node as module/sub-module,
452 * then sends the list of nodes for finding the target leaf.
453 */
454 if (leafref.getPathType() == YangPathArgType.ABSOLUTE_PATH) {
455 List<YangAtomicPath> atomicPathList = leafref.getAtomicPath();
456 if (atomicPathList != null && !atomicPathList.isEmpty()) {
457 Iterator<YangAtomicPath> listOfYangAtomicPath = atomicPathList.listIterator();
458 if (getCurReferenceResolver() instanceof YangModule) {
459 YangModule rootNode = (YangModule) getCurReferenceResolver();
460 // Sends list of nodes for finding the target leaf.
461 referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
462 referredLeafFound, potentialAncestorWithReferredNode);
463 } else if (getCurReferenceResolver() instanceof YangSubModule) {
464 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
465 // Sends list of nodes for finding the target leaf.
466 referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
467 referredLeafFound, potentialAncestorWithReferredNode);
468 }
469 }
470 /*
471 * Takes relative path, goes to the parent node by using the
472 * ancestor count and sends the list of nodes for finding the target
473 * leaf.
474 */
475 } else if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
476 YangRelativePath yangRelativePath = leafref.getRelativePath();
477 int parentNodes = yangRelativePath.getAncestorNodeCount();
478 List<YangAtomicPath> atomicPathList = yangRelativePath.getAtomicPathList();
479 if (atomicPathList != null && !atomicPathList.isEmpty()) {
480 Iterator<YangAtomicPath> listOfAtomicPath = atomicPathList.listIterator();
481 // Gets the root node from ancestor count.
482 YangNode rootparentNode = getRootNodeWithAncestorCount(parentNodes, ancestorWithTheReferredNode);
483 // Sends list of nodes for finding the target leaf.
484 referredLeafFound = isLeafReferenceFound(listOfAtomicPath, rootparentNode,
485 referredLeafFound, potentialAncestorWithReferredNode);
486 }
487 }
488 if (referredLeafFound) {
489 return;
490 }
491 /*
492 * In case prefix is not present it's a candidate for inter-file
493 * resolution via include list.
494 */
495 if (getRefPrefix() == null) {
496 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
497 }
498 }
499
500 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530501 * Resolves self file linking for base/identityref.
502 *
503 * @throws DataModelException a violation of data model rules
504 */
505 private void resolveSelfFileLinkingForBaseAndIdentityref()
506 throws DataModelException {
507
508 boolean referredIdentityFound = false;
509 String nodeName = null;
510
511 if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
512 nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
513 }
514
515 if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
516 nodeName = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName();
517 }
518
519 if (getCurReferenceResolver() instanceof YangModule) {
520 YangModule rootNode = (YangModule) getCurReferenceResolver();
521 // Sends list of nodes for finding the target identity.
522 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
523 } else if (getCurReferenceResolver() instanceof YangSubModule) {
524 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
525 // Sends list of nodes for finding the target identity.
526 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
527 }
528
529 if (referredIdentityFound) {
530 return;
531 }
532
533 /*
534 * In case prefix is not present it's a candidate for inter-file resolution via include list.
535 */
536 if (getRefPrefix() == null) {
537 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
538 }
539 }
540
541 /**
janani be18b5342016-07-13 21:06:41 +0530542 * Returns the root parent with respect to the ancestor count from leafref.
543 *
544 * @param ancestorCount count of node where parent node can be reached
545 * @param currentParent current parent node
546 * @return root node
547 * @throws DataModelException a violation of data model rules
548 */
549 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
550 throws DataModelException {
551
552 int currentParentCount = 1;
553 while (currentParentCount < ancestorCount) {
554 if (currentParent.getParent() == null) {
555 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
556 }
557 currentParent = currentParent.getParent();
558 currentParentCount = currentParentCount + 1;
559 }
560 return currentParent;
561 }
562
563 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530564 * Resolves self file linking for if-feature.
565 *
566 * @param potentialAncestorWithReferredNode if-feature holder node
567 * @throws DataModelException DataModelException a violation of data model
568 * rules
569 */
570 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
571 throws DataModelException {
572
573 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
574 YangNode potentialReferredNode = (YangNode) featureHolder;
575 if (isReferredNode(potentialReferredNode)) {
576
577 // Adds reference link of entity to the node under resolution.
578 addReferredEntityLink(potentialReferredNode, LINKED);
579
580 /**
581 * resolve the reference and update the partial resolution stack
582 * with any further recursive references
583 */
584 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
585 return;
586 }
587
588 /*
589 * In case prefix is not present it's a candidate for inter-file
590 * resolution via include list.
591 */
592 if (getRefPrefix() == null) {
593 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
594 }
595 }
596
janani be18b5342016-07-13 21:06:41 +0530597 /**
598 * Returns the status of the referred leaf/leaf-list found for leafref.
599 *
600 * @param listOfYangAtomicPath list of atomic paths
601 * @param ancestorWithTheReferredNode the parent node of leafref
602 * @param referredLeafFound status of referred leaf/leaf-list
603 * @param potentialAncestorWithReferredNode holder of the leafref leaf
604 * @return status of referred leaf
605 * @throws DataModelException a violation of data model rules
606 */
607 private boolean isLeafReferenceFound(Iterator<YangAtomicPath> listOfYangAtomicPath,
608 YangNode ancestorWithTheReferredNode, boolean referredLeafFound, YangNode potentialAncestorWithReferredNode)
609 throws DataModelException {
610
611 while (listOfYangAtomicPath.hasNext()) {
612 YangAtomicPath atomicPath = listOfYangAtomicPath.next();
613 String nodeName = atomicPath.getNodeIdentifier().getName();
614
615 // When child is not present, only leaf/leaf-list is available in the node.
616 if (ancestorWithTheReferredNode.getChild() == null) {
617 referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode, nodeName, (T) LINKED);
618 break;
619 }
620 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
621
622 // Checks all the siblings under the node and returns the matched node.
623 YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(ancestorWithTheReferredNode, nodeName);
624
625 // When node is not found in all the siblings, leaf-list may be the node we have to find.
626 if (nodeFound == null) {
627 referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode.getParent(), nodeName,
628 (T) LINKED);
629 } else {
630 ancestorWithTheReferredNode = nodeFound;
631
632 // For the node check if path predicate is present and fill its values.
633 List<YangPathPredicate> pathPredicateList = atomicPath.getPathPredicatesList();
634 if (pathPredicateList != null && !pathPredicateList.isEmpty()) {
635 Iterator<YangPathPredicate> listOfYangPathPredicate = pathPredicateList.listIterator();
636 fillPathPredicatesForTheNode(ancestorWithTheReferredNode, listOfYangPathPredicate,
637 potentialAncestorWithReferredNode);
638 }
639 }
640
641 // If leaf is also not found and node is also not found return the status as false.
642 if (!referredLeafFound && nodeFound == null) {
643 break;
644 }
645 }
646 return referredLeafFound;
647 }
648
649 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530650 * Returns the status of the referred identity found for base/identityref.
651 *
652 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
653 * @param ancestorWithTheReferredNode the parent node of base/identityref
654 * @return status of referred base/identityref
655 * @throws DataModelException a violation of data model rules
656 */
657 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
658 throws DataModelException {
659
660 // When child is not present return.
661 if (ancestorWithTheReferredNode.getChild() == null) {
662 return false;
663 }
664
665 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
666
667 // Checks all the siblings under the node and returns the matched node.
668 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
669
670 if (nodeFound != null) {
671 // Adds reference link of entity to the node under resolution.
672 addReferredEntityLink(nodeFound, LINKED);
673
674 /**
675 * resolve the reference and update the partial resolution stack with any further recursive references
676 */
677 addUnresolvedRecursiveReferenceToStack(nodeFound);
678 return true;
679 }
680
681 return false;
682 }
683
684 /**
janani be18b5342016-07-13 21:06:41 +0530685 * Fills the referred leaf or leaf-list inside the path predicates.
686 *
687 * @param ancestorWithTheReferredNode the actual node where YANG list will be present
688 * @param listOfYangPathPredicate the path predicates present for the node
689 * @param potentialAncestorWithReferredNode the current leaf node parent
690 * @throws DataModelException a violation of data model rules
691 */
692 private void fillPathPredicatesForTheNode(YangNode ancestorWithTheReferredNode,
693 Iterator<YangPathPredicate> listOfYangPathPredicate, YangNode potentialAncestorWithReferredNode)
694 throws DataModelException {
695
696 while (listOfYangPathPredicate.hasNext()) {
697 if (!(ancestorWithTheReferredNode instanceof YangList)) {
698 throw new DataModelException("YANG file error: The path predicates are applicable only for list");
699 }
700 YangPathPredicate pathPredicate = listOfYangPathPredicate.next();
701 YangNodeIdentifier leftNode = pathPredicate.getNodeIdentifier();
702 YangRelativePath relativePath = pathPredicate.getRightRelativePath();
703
704 // Checks that the left axis is filled in the path predicate.
705 boolean isLeftLeafOrLeafListSetForLeftAxis = getLeftLeafOrLeafListInPredicate(
706 (YangList) ancestorWithTheReferredNode, pathPredicate, leftNode);
707 if (!isLeftLeafOrLeafListSetForLeftAxis) {
708 throw new DataModelException(
709 "YANG file error: The path predicate is not referring to an existing leaf/leaflist");
710 }
711 int parentNodes = relativePath.getAncestorNodeCount();
712
713 // Finds the root node for the right relative path.
714 YangNode rootParentNode = getRootNodeWithAncestorCount(parentNodes, potentialAncestorWithReferredNode);
715
716 // Finds the leaf/leaf-list from the right side relative path.
717 resolveRightAxisNodeInPathPredicate(relativePath, rootParentNode, pathPredicate);
718 }
719 }
720
721 /**
722 * Resolves the right axis node in the path predicate.
723 *
724 * @param relativePath the relative path in the path predicate
725 * @param rootParentNode parent node from where the node has to be found
726 * @param pathPredicate data tree reference in YANG list
727 * @throws DataModelException a violation of data model rules
728 */
729 private void resolveRightAxisNodeInPathPredicate(YangRelativePath relativePath, YangNode rootParentNode,
730 YangPathPredicate pathPredicate) throws DataModelException {
731
732 List<YangAtomicPath> absolutePathList = relativePath.getAtomicPathList();
733 if (absolutePathList != null && !absolutePathList.isEmpty()) {
734 Iterator<YangAtomicPath> listOfYangAtomicPathForRightRelative = absolutePathList.listIterator();
735 while (listOfYangAtomicPathForRightRelative.hasNext()) {
736 boolean isRightAxisNodeFound = false;
737 YangAtomicPath absolutePathInPredicate = listOfYangAtomicPathForRightRelative.next();
738 String nodeNameInAtomicPath = absolutePathInPredicate.getNodeIdentifier().getName();
739
740 // When child is not there check the leaf/leaf-list.
741 if (rootParentNode.getChild() == null) {
742 isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode,
743 nodeNameInAtomicPath, (T) pathPredicate);
744 if (!isRightAxisNodeFound) {
745 throw new DataModelException(
746 "YANG file error: The path predicates is not referring to an existing leaf/leaflist");
747 }
748 break;
749 }
750 rootParentNode = rootParentNode.getChild();
751 YangNode nodeFoundInTheRelativePath = isReferredNodeInSiblingProcessedForLeafref(
752 rootParentNode, nodeNameInAtomicPath);
753
754 if (nodeFoundInTheRelativePath == null) {
755
756 // When node is not found check the leaf/leaf-list.
757 isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode.getParent(),
758 nodeNameInAtomicPath, (T) pathPredicate);
759 } else {
760 rootParentNode = nodeFoundInTheRelativePath;
761 }
762 if (!isRightAxisNodeFound && nodeFoundInTheRelativePath == null) {
763 throw new DataModelException(
764 "YANG file error: The path predicates is not referring to an existing leaf/leaflist");
765 }
766 }
767 }
768 }
769
770 /**
771 * Returns the status, if referred leaf/leaf-list is found.
772 *
773 * @param ancestorWithTheReferredNode the parent node of leaf/leaf-list
774 * @param nodeName the name of the leaf/leaf-list
775 * @param statusOrPathPredicate the status to be set for the leaf-ref or the path predicate
776 * @return status of the target node is found
777 * @throws DataModelException a violation of data model rules
778 */
779 private boolean isReferredLeafOrLeafListFound(YangNode ancestorWithTheReferredNode, String nodeName,
780 T statusOrPathPredicate) throws DataModelException {
781
782 if (!(ancestorWithTheReferredNode instanceof YangLeavesHolder)) {
783 throw new DataModelException("Yang file error: The target node of leafref is invalid.");
784 }
785 YangLeavesHolder leavesHolder = (YangLeavesHolder) ancestorWithTheReferredNode;
786 if (leavesHolder.getListOfLeaf() != null) {
787 Iterator<YangLeaf> yangLeavesList = leavesHolder.getListOfLeaf().listIterator();
788 while (yangLeavesList.hasNext()) {
789 YangLeaf yangleaf = yangLeavesList.next();
790 if (yangleaf.getName().contentEquals(nodeName)) {
791 if (statusOrPathPredicate instanceof ResolvableStatus) {
792 ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
793
794 // Sets the referred leaf to YANG leafref.
795 ((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangleaf);
796
797 // Adds reference link of entity to the node under resolution.
798 addReferredEntityLink(ancestorWithTheReferredNode, status);
799 addUnResolvedLeafRefTypeToStack((T) yangleaf, ancestorWithTheReferredNode);
800 return true;
801 } else if (statusOrPathPredicate instanceof YangPathPredicate) {
802 YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
803
804 // Sets the right axis node.
805 pathPredicate.setRightAxisNode(yangleaf);
806 return true;
807 } else {
808 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
809 }
810 }
811 }
812 }
813 if (leavesHolder.getListOfLeafList() != null) {
814 Iterator<YangLeafList> yangLeafListList = leavesHolder.getListOfLeafList().listIterator();
815 while (yangLeafListList.hasNext()) {
816 YangLeafList yangLeaflist = yangLeafListList.next();
817 if (yangLeaflist.getName().contentEquals(nodeName)) {
818 if (statusOrPathPredicate instanceof ResolvableStatus) {
819 ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
820
821 // Sets the referred leaf-list to YANG leafref.
822 ((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangLeaflist);
823
824 // Adds reference link of entity to the node under resolution.
825 addReferredEntityLink(ancestorWithTheReferredNode, status);
826 addUnResolvedLeafRefTypeToStack((T) yangLeaflist, ancestorWithTheReferredNode);
827 return true;
828 } else if (statusOrPathPredicate instanceof YangPathPredicate) {
829 YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
830 pathPredicate.setRightAxisNode(yangLeaflist);
831 return true;
832 } else {
833 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
834 }
835 }
836 }
837 }
838 return false;
839 }
840
841 /**
842 * Adds the unresolved constructs to stack which has to be resolved for leafref.
843 *
844 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
845 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
846 */
847 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
848
849 YangType referredTypeInLeafOrLeafList;
850 if (yangleafOrLeafList instanceof YangLeaf) {
851 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
852 referredTypeInLeafOrLeafList = leaf.getDataType();
853 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
854 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
855 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
856 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
857 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
858 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
859 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
860 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
861 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
862 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
863 }
864 } else {
865 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
866 referredTypeInLeafOrLeafList = leafList.getDataType();
867 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
868 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
869 unResolvedEntityInfo
870 .setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
871 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
872 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
873 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
874 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
875 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
876 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
877 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
878 }
879 }
880 }
881
882 /**
883 * Returns true if referred leaf/leaf-list is found in a particular node. This is for path in path predicate.
884 *
885 * @param listForLeaf list node where referred leaf is found
886 * @param pathPredicate path predicate instance where the value of nodes to be found are available
887 * @param leftNode node identifier of the left side parameter in path predicate
888 * @return status of the leaf/leaf-list found
889 */
890 private boolean getLeftLeafOrLeafListInPredicate(YangList listForLeaf, YangPathPredicate pathPredicate,
891 YangNodeIdentifier leftNode) {
892
893 if (listForLeaf.getListOfLeaf() != null) {
894 Iterator<YangLeaf> yangLeavesUnderList = listForLeaf.getListOfLeaf().listIterator();
895 while (yangLeavesUnderList.hasNext()) {
896 YangLeaf yangleafUnderList = yangLeavesUnderList.next();
897 if (yangleafUnderList.getName().contentEquals(leftNode.getName())) {
898 pathPredicate.setLeftAxisNode(yangleafUnderList);
899 return true;
900 }
901 }
902 }
903 if (listForLeaf.getListOfLeafList() != null) {
904 Iterator<YangLeafList> yangLeavesListUnderList = listForLeaf.getListOfLeafList().listIterator();
905 while (yangLeavesListUnderList.hasNext()) {
906 YangLeafList yangleafListUnderList = yangLeavesListUnderList.next();
907 if (yangleafListUnderList.getName().contentEquals(leftNode.getName())) {
908 pathPredicate.setLeftAxisNode(yangleafListUnderList);
909 return true;
910 }
911 }
912 }
913 return false;
914 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530915
916 /**
917 * Returns feature holder(module/sub-module node) .
918 *
919 * @param potentialAncestorWithReferredNode if-feature holder node
920 */
921 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
922 while (potentialAncestorWithReferredNode != null) {
923 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
924 return (YangFeatureHolder) potentialAncestorWithReferredNode;
925 }
926 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
927 }
928 return null;
929 }
930
931 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530932 * Checks if the reference in self file or in external file.
933 *
934 * @return true if self file reference, false otherwise
935 * @throws DataModelException a violation of data model rules
936 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530937 private boolean isCandidateForSelfFileReference()
938 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530939 String prefix = getRefPrefix();
940 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
941 }
942
943 /**
janani be18b5342016-07-13 21:06:41 +0530944 * Checks for the referred parent node for the leafref path.
945 *
946 * @param potentialReferredNode potential referred node
947 * @return the reffered parent node of leaf/leaf-list
948 * @throws DataModelException data model errors
949 */
950 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
951 throws DataModelException {
952
953 while (potentialReferredNode != null) {
954 if (potentialReferredNode instanceof YangInput) {
955 if (referredNodeName.equalsIgnoreCase(INPUT)) {
956 return potentialReferredNode;
957 }
958 } else if (potentialReferredNode instanceof YangOutput) {
959 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
960 return potentialReferredNode;
961 }
962 }
963 // Check if the potential referred node is the actual referred node
964 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
965 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
966 if (potentialReferredNode.getParent() instanceof YangRpc) {
967 potentialReferredNode = potentialReferredNode.getNextSibling();
968 } else {
969 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
970 }
971 }
972 return potentialReferredNode;
973 }
974 potentialReferredNode = potentialReferredNode.getNextSibling();
975 }
976 return null;
977 }
978
979 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530980 * Checks for the referred parent node for the base/identity.
981 *
982 * @param potentialReferredNode potential referred node
983 * @return the reffered parent node of base/identity.
984 * @throws DataModelException data model errors
985 */
986 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
987 String referredNodeName) throws DataModelException {
988
989 while (potentialReferredNode != null) {
990 if (potentialReferredNode instanceof YangIdentity) {
991 // Check if the potential referred node is the actual referred node
992 if (isReferredNodeForIdentity(potentialReferredNode, referredNodeName)) {
993 return potentialReferredNode;
994 }
995 }
996 potentialReferredNode = potentialReferredNode.getNextSibling();
997 }
998 return null;
999 }
1000
1001 /**
janani be18b5342016-07-13 21:06:41 +05301002 * Checks if the current reference node name and the name in the path are equal.
1003 *
1004 * @param currentReferredNode the node where the reference is pointed
1005 * @param nameOfNodeinPath name of the node in the path
1006 * @return status of the match between the name
1007 * @throws DataModelException a violation of data model rules
1008 */
1009 private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
1010 throws DataModelException {
1011
1012 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1013 /*
1014 * Check if name of node name matches with the current reference
1015 * node.
1016 */
1017 return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
1018 } else {
1019 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
1020 }
1021 }
1022
1023 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301024 * Checks if the current reference node name and the name in the base/identityref base are equal.
1025 *
1026 * @param currentReferredNode the node where the reference is pointed
1027 * @param nameOfIdentityRefBase name of the base in the base/identityref base
1028 * @return status of the match between the name
1029 * @throws DataModelException a violation of data model rules
1030 */
1031 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
1032 throws DataModelException {
1033
1034 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
1035 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
1036 /*
1037 * Check if name of node name matches with the current reference node.
1038 */
1039 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
1040 } else {
1041 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref");
1042 }
1043 }
1044
1045 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301046 * Checks for the referred node defined in a ancestor scope.
1047 *
1048 * @param potentialReferredNode potential referred node
1049 * @return status of resolution and updating the partial resolved stack with
1050 * the any recursive references
janani be18b5342016-07-13 21:06:41 +05301051 * @throws DataModelException a violation of data model rules
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301052 */
1053 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
1054 throws DataModelException {
1055 while (potentialReferredNode != null) {
1056
1057 // Check if the potential referred node is the actual referred node
1058 if (isReferredNode(potentialReferredNode)) {
1059
1060 // Adds reference link of entity to the node under resolution.
1061 addReferredEntityLink(potentialReferredNode, LINKED);
1062
1063 /**
1064 * resolve the reference and update the partial resolution stack
1065 * with any further recursive references
1066 */
1067 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
1068
1069 /*
1070 * return true, since the reference is linked and any recursive
1071 * unresolved references is added to the stack
1072 */
1073 return true;
1074 }
1075
1076 potentialReferredNode = potentialReferredNode.getNextSibling();
1077 }
1078 return false;
1079 }
1080
1081 /**
1082 * Checks if the potential referred node is the actual referred node.
1083 *
1084 * @param potentialReferredNode typedef/grouping node
1085 * @return true if node is of resolve type otherwise false
1086 * @throws DataModelException a violation of data model rules
1087 */
1088 private boolean isReferredNode(YangNode potentialReferredNode)
1089 throws DataModelException {
1090 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1091 if (potentialReferredNode instanceof YangTypeDef) {
1092 /*
1093 * Check if name of node name matches with the entity being
1094 * resolved
1095 */
1096 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1097 }
1098 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1099 if (potentialReferredNode instanceof YangGrouping) {
1100 /*
1101 * Check if name of node name matches with the entity being
1102 * resolved
1103 */
1104 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1105 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301106 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1107 if (potentialReferredNode instanceof YangFeatureHolder) {
1108 /*
1109 * Check if name of node name matches with the entity being
1110 * resolved
1111 */
1112 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1113 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301114 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1115 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
1116 if (potentialReferredNode instanceof YangIdentity) {
1117 /*
1118 * Check if name of node name matches with the entity being
1119 * resolved
1120 */
1121 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1122 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301123 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301124 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
1125 "uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301126 }
1127 return false;
1128 }
1129
1130 /**
1131 * Checks if node name is same as name in resolution info, i.e. name of
1132 * typedef/grouping is same as name of type/uses.
1133 *
1134 * @param node typedef/grouping node
1135 * @return true if node name is same as name in resolution info, otherwise
1136 * false
1137 * @throws DataModelException a violation of data model rules
1138 */
1139
1140 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
1141 throws DataModelException {
1142 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1143 if (node.getName().contentEquals(
1144 ((YangType<?>) getCurrentEntityToResolveFromStack())
1145 .getDataTypeName())) {
1146 return true;
1147 }
1148 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1149 if (node.getName().contentEquals(
1150 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1151 return true;
1152 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301153 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1154 return isFeatureDefinedInNode(node);
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301155 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1156 if (node.getName().contentEquals(
1157 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1158 return true;
1159 }
1160 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1161 if (node.getName().contentEquals(
1162 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
1163 return true;
1164 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301165 } else {
1166 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1167 }
1168 return false;
1169 }
1170
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301171 private boolean isFeatureDefinedInNode(YangNode node) throws DataModelException {
1172 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1173 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
1174 if (featureList != null && !featureList.isEmpty()) {
1175 Iterator<YangFeature> iterator = featureList.iterator();
1176 while (iterator.hasNext()) {
1177 YangFeature feature = iterator.next();
1178 if (ifFeature.getName().equals(feature.getName())) {
1179 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1180 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
1181 return true;
1182 }
1183 }
1184 }
1185 return false;
1186 }
1187
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301188 /**
1189 * Adds reference of grouping/typedef in uses/type.
1190 *
1191 * @param referredNode grouping/typedef node being referred
1192 * @param linkedStatus linked status if success.
1193 * @throws DataModelException a violation of data model rules
1194 */
1195 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
1196 throws DataModelException {
1197 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswal96dfef02016-06-16 00:29:12 +05301198 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1199 .getDataTypeExtendedInfo();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301200 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
1201 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1202 ((YangUses) getCurrentEntityToResolveFromStack())
1203 .setRefGroup((YangGrouping) referredNode);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301204 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1205 // do nothing , referred node is already set
janani be18b5342016-07-13 21:06:41 +05301206 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1207 // do nothing , referred node is already set
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301208 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1209 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
1210 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1211 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301212 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301213 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
1214 "/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301215 }
1216
1217 // Sets the resolution status in inside the type/uses.
1218 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
1219 }
1220
1221 /**
1222 * Checks if type/grouping has further reference to typedef/ unresolved
1223 * uses. Add it to the partial resolve stack and return the status of
1224 * addition to stack.
1225 *
1226 * @param referredNode grouping/typedef node
1227 * @throws DataModelException a violation of data model rules
1228 */
1229 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
1230 throws DataModelException {
1231 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1232 /*
1233 * Checks if typedef type is derived
1234 */
Bharat saraswal96dfef02016-06-16 00:29:12 +05301235 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301236
Bharat saraswal96dfef02016-06-16 00:29:12 +05301237 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301238 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
1239 .getTypeDefBaseType());
1240 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301241 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301242 }
1243
1244 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1245 /*
1246 * Search if the grouping has any un resolved uses child, if so
1247 * return true, else return false.
1248 */
1249 addUnResolvedUsesToStack(referredNode);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301250 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1251 addUnResolvedIfFeatureToStack(referredNode);
janani be18b5342016-07-13 21:06:41 +05301252 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1253 // do nothing , referred node is already set
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301254 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301255 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1256 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
1257 /*
1258 * Search if the identity has any un resolved base, if so return true, else return false.
1259 */
1260 addUnResolvedBaseToStack(referredNode);
1261 } else {
1262 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
1263 "base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301264 }
1265 }
1266
1267 /**
1268 * Returns if there is any unresolved uses in grouping.
1269 *
1270 * @param node grouping/typedef node
1271 */
1272 private void addUnResolvedUsesToStack(YangNode node) {
1273
1274 /**
1275 * Search the grouping node's children for presence of uses node.
1276 */
1277 YangNode curNode = node.getChild();
1278 while (curNode != null) {
1279 if (curNode instanceof YangUses) {
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301280 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301281 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1282 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301283 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301284
1285 }
1286 curNode = curNode.getNextSibling();
1287 }
1288 }
1289
1290 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301291 * Returns if there is any unresolved if-feature in feature.
1292 *
1293 * @param node module/submodule node
1294 */
1295 private void addUnResolvedIfFeatureToStack(YangNode node) {
1296 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1297 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1298 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1299 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1300 while (ifFeatureIterator.hasNext()) {
1301 YangIfFeature ifFeature = ifFeatureIterator.next();
1302 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1303 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1304 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1305 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1306 }
1307 }
1308 }
1309
1310 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301311 * Returns if there is any unresolved base in identity.
1312 *
1313 * @param node module/submodule node
1314 */
1315 private void addUnResolvedBaseToStack(YangNode node) {
1316
1317 YangIdentity curNode = (YangIdentity) node;
1318 if (curNode.getBaseNode() != null) {
1319 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1320 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1321 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1322 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1323 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1324
1325 }
1326 }
1327 }
1328
1329
1330 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301331 * Returns stack of YANG type with partially resolved YANG construct
1332 * hierarchy.
1333 *
1334 * @return partial resolved YANG construct stack
1335 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301336 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301337 return partialResolvedStack;
1338 }
1339
1340 /**
1341 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1342 *
1343 * @param partialResolvedStack partial resolved YANG construct stack
1344 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301345 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301346 this.partialResolvedStack = partialResolvedStack;
1347 }
1348
1349 /**
1350 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1351 *
1352 * @param partialResolvedInfo partial resolved YANG construct stack
1353 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301354 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301355 getPartialResolvedStack().push(partialResolvedInfo);
1356 }
1357
1358 /**
1359 * Retrieves the next entity in the stack that needs to be resolved. It is
1360 * assumed that the caller ensures that the stack is not empty.
1361 *
1362 * @return next entity in the stack that needs to be resolved
1363 */
1364 private T getCurrentEntityToResolveFromStack() {
1365 return getPartialResolvedStack().peek().getEntityToResolve();
1366 }
1367
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301368 @Override
1369 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301370 return entityToResolveInfo;
1371 }
1372
1373 /**
1374 * Sets information about the entity that needs to be resolved.
1375 *
1376 * @param entityToResolveInfo information about the entity that needs to be
1377 * resolved
1378 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301379 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301380 this.entityToResolveInfo = entityToResolveInfo;
1381 }
1382
1383 @Override
1384 public int getLineNumber() {
1385 return lineNumber;
1386 }
1387
1388 @Override
1389 public int getCharPosition() {
1390 return charPosition;
1391 }
1392
1393 @Override
1394 public void setLineNumber(int lineNumber) {
1395 this.lineNumber = lineNumber;
1396 }
1397
1398 @Override
1399 public void setCharPosition(int charPositionInLine) {
1400 this.charPosition = charPositionInLine;
1401 }
1402
1403 /**
1404 * Returns current module/sub-module reference, will be used in inter-file/
1405 * inter-jar scenario to get the import/include list.
1406 *
1407 * @return current module/sub-module reference
1408 */
1409 private YangReferenceResolver getCurReferenceResolver() {
1410 return curReferenceResolver;
1411 }
1412
1413 /**
1414 * Sets current module/sub-module reference, will be used in inter-file/
1415 * inter-jar scenario to get the import/include list.
1416 *
1417 * @param curReferenceResolver current module/sub-module reference
1418 */
1419 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1420 this.curReferenceResolver = curReferenceResolver;
1421 }
1422
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301423 @Override
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301424 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1425 throws DataModelException {
1426
1427 setCurReferenceResolver(dataModelRootNode);
1428
1429 // Current node to resolve, it can be a YANG type or YANG uses.
1430 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1431
1432 // Check if linking is already done
1433 if (entityToResolve instanceof Resolvable) {
1434 Resolvable resolvable = (Resolvable) entityToResolve;
1435 if (resolvable.getResolvableStatus() == RESOLVED) {
1436 return;
1437 }
1438 } else {
1439 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1440 }
1441
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301442 if (entityToResolve instanceof YangXPathResolver) {
1443 //Process x-path linking.
1444 processXPathLinking(getEntityToResolveInfo(), dataModelRootNode);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301445
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301446 } else {
janani be18b5342016-07-13 21:06:41 +05301447
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301448 // Push the initial entity to resolve in stack.
1449 addInPartialResolvedStack(getEntityToResolveInfo());
1450
1451 // Inter file linking and resolution.
1452 linkInterFileAndResolve();
1453
1454 addDerivedRefTypeToRefTypeResolutionList();
1455 }
1456 }
1457
1458 /**
1459 * Process x-path linking for augment and leaf-ref.
1460 *
1461 * @param entityToResolveInfo entity to resolve
1462 * @param root root node
1463 */
1464 private void processXPathLinking(YangEntityToResolveInfoImpl<T> entityToResolveInfo,
1465 YangReferenceResolver root) {
1466 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
1467 T entityToResolve = entityToResolveInfo.getEntityToResolve();
1468 if (entityToResolve instanceof YangAugment) {
1469 YangNode targetNode = null;
1470 YangAugment augment = (YangAugment) entityToResolve;
1471 targetNode = xPathLinker.processAugmentXpathLinking(augment.getTargetNode(),
1472 (YangNode) root);
1473 if (targetNode != null) {
1474 if (targetNode instanceof YangAugmentableNode) {
1475 detectCollisionForAugmentedNode(targetNode, augment);
1476 ((YangAugmentableNode) targetNode).addAugmentation(augment);
1477 augment.setAugmentedNode(targetNode);
Bharat saraswalb551aae2016-07-14 15:18:20 +05301478 augment.setResolveNodeInPath(xPathLinker.getResolvedNodes());
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301479 Resolvable resolvable = (Resolvable) entityToResolve;
1480 resolvable.setResolvableStatus(RESOLVED);
1481 } else {
1482 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for "
1483 + augment.getName());
1484 }
1485 } else {
1486 throw new LinkerException("Failed to link " + augment.getName());
1487 }
1488 } else if (entityToResolve instanceof YangLeafRef) {
1489 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
1490 Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
1491 (YangNode) root);
1492 if (target != null) {
1493 YangLeaf leaf = null;
1494 YangLeafList leafList = null;
1495 leafRef.setReferredLeafOrLeafList(target);
1496 if (target instanceof YangLeaf) {
1497 leaf = (YangLeaf) target;
1498 leafRef.setEffectiveDataType(leaf.getDataType());
1499 } else {
1500 leafList = (YangLeafList) target;
1501 leafRef.setEffectiveDataType(leafList.getDataType());
1502 }
1503 leafRef.setResolvableStatus(RESOLVED);
1504 //TODO: add logic for leaf-ref for path predicates.
1505 } else {
1506 throw new LinkerException("YANG file error: Unable to find base leaf/leaf-list for given leafref "
1507 + leafRef.getPath());
1508 }
1509 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301510 }
1511
1512 /**
1513 * Returns the referenced prefix of entity under resolution.
1514 *
1515 * @return referenced prefix of entity under resolution
1516 * @throws DataModelException a violation in data model rule
1517 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301518 private String getRefPrefix()
1519 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301520 String refPrefix;
1521 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1522 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1523 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1524 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301525 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1526 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
janani be18b5342016-07-13 21:06:41 +05301527 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1528 refPrefix = refPrefixForLeafRef();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301529 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1530 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1531 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1532 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301533 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301534 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
1535 "type/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301536 }
1537 return refPrefix;
1538 }
1539
1540 /**
janani be18b5342016-07-13 21:06:41 +05301541 * Returns the referenced prefix for leafref under resolution.
1542 *
1543 * @return referenced prefix of leafref under resolution
1544 */
1545 private String refPrefixForLeafRef() {
1546
1547 String refPrefix;
1548 if (((YangLeafRef) getCurrentEntityToResolveFromStack()).getPathType() == YangPathArgType.ABSOLUTE_PATH) {
1549 List<YangAtomicPath> theList = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getAtomicPath();
1550 YangAtomicPath absPath = theList.iterator().next();
1551 refPrefix = absPath.getNodeIdentifier().getPrefix();
1552 } else {
1553 YangRelativePath relativePath = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getRelativePath();
1554 List<YangAtomicPath> theList = relativePath.getAtomicPathList();
1555 YangAtomicPath absPath = theList.iterator().next();
1556 refPrefix = absPath.getNodeIdentifier().getPrefix();
1557 }
1558 return refPrefix;
1559 }
1560
1561 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301562 * Performs inter file linking and resolution.
1563 *
1564 * @throws DataModelException a violation in data model rule
1565 */
1566 private void linkInterFileAndResolve()
1567 throws DataModelException {
1568
1569 while (getPartialResolvedStack().size() != 0) {
1570
1571 // Current node to resolve, it can be a YANG type or YANG uses.
1572 T entityToResolve = getCurrentEntityToResolveFromStack();
1573 // Check if linking is already done
1574 if (entityToResolve instanceof Resolvable) {
1575
1576 Resolvable resolvable = (Resolvable) entityToResolve;
1577 switch (resolvable.getResolvableStatus()) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301578 case RESOLVED: {
1579 /*
1580 * If the entity is already resolved in the stack, then pop
1581 * it and continue with the remaining stack elements to
1582 * resolve
1583 */
1584 getPartialResolvedStack().pop();
1585 break;
1586 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301587
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301588 case INTER_FILE_LINKED: {
1589 /*
1590 * If the top of the stack is already linked then resolve
1591 * the references and pop the entity and continue with
1592 * remaining stack elements to resolve
1593 */
1594 resolveTopOfStack(INTER_FILE);
1595 getPartialResolvedStack().pop();
1596 break;
1597 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301598
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301599 case INTRA_FILE_RESOLVED: {
1600 /*
1601 * If the top of the stack is intra file resolved then check
1602 * if top of stack is linked, if not link it using
1603 * import/include list and push the linked referred entity
1604 * to the stack, otherwise only push it to the stack.
1605 */
1606 linkInterFileTopOfStackRefUpdateStack();
1607 break;
1608 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301609
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301610 case UNDEFINED: {
1611 /*
1612 * In case of if-feature resolution, if referred "feature" is not
1613 * defined then the resolvable status will be undefined.
1614 */
1615 getPartialResolvedStack().pop();
1616 break;
1617 }
1618
1619 default: {
1620 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1621 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301622
1623 }
1624
1625 } else {
1626 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1627 }
1628
1629 }
1630
1631 }
1632
1633 /**
1634 * Links the top of the stack if it's inter-file and update stack.
1635 *
1636 * @throws DataModelException data model error
1637 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301638 private void linkInterFileTopOfStackRefUpdateStack()
1639 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301640
1641 /*
1642 * Obtain the referred node of top of stack entity under resolution
1643 */
1644 T referredNode = getRefNode();
1645
1646 /*
1647 * Check for null for scenario when it's not linked and inter-file
1648 * linking is required.
1649 */
1650 if (referredNode == null) {
1651
1652 /*
Bharat saraswal96dfef02016-06-16 00:29:12 +05301653 * Check if prefix is null or not, to identify whether to search in
1654 * import list or include list.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301655 */
Bharat saraswalcad0e652016-05-26 23:48:38 +05301656 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301657 if (resolveWithImport()) {
1658 return;
1659 }
1660 } else {
1661 if (resolveWithInclude()) {
1662 return;
1663 }
1664 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301665
1666 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1667 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1668 return;
1669 }
janani be18b5342016-07-13 21:06:41 +05301670 // If current entity is still not resolved, then
1671 // linking/resolution has failed.
1672 String errorInfo;
1673 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1674 errorInfo = TYPEDEF_LINKER_ERROR;
1675 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1676 errorInfo = GROUPING_LINKER_ERROR;
1677 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1678 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301679 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1680 errorInfo = BASE_LINKER_ERROR;
1681 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1682 errorInfo = IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +05301683 } else {
1684 errorInfo = LEAFREF_LINKER_ERROR;
1685 }
1686 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301687 dataModelException.setLine(getLineNumber());
1688 dataModelException.setCharPosition(getCharPosition());
1689 throw dataModelException;
1690 } else {
1691 /*
1692 * If referred node is already linked, then just change the status
1693 * and push to the stack.
1694 */
janani be18b5342016-07-13 21:06:41 +05301695 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1696 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1697 if (referredNode instanceof YangLeaf) {
1698 YangLeaf yangleaf = (YangLeaf) referredNode;
1699 addUnResolvedLeafRefTypeToStack((T) yangleaf, (YangNode) yangleaf.getContainedIn());
1700 } else if (referredNode instanceof YangLeafList) {
1701 YangLeafList yangLeafList = (YangLeafList) referredNode;
1702 addUnResolvedLeafRefTypeToStack((T) yangLeafList, (YangNode) yangLeafList.getContainedIn());
1703 }
1704 } else {
1705 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1706 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1707 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301708 }
1709 }
1710
1711 /**
1712 * Finds and resolves with include list.
1713 *
1714 * @return true if resolved, false otherwise
1715 * @throws DataModelException a violation in data model rule
1716 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301717 private boolean resolveWithInclude()
1718 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301719 /*
1720 * Run through all the nodes in include list and search for referred
1721 * typedef/grouping at the root level.
1722 */
1723 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1724 YangNode linkedNode = null;
1725 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1726 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1727 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1728 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301729 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1730 linkedNode = findRefFeature(yangInclude.getIncludedNode());
janani be18b5342016-07-13 21:06:41 +05301731 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1732 boolean referredNode = findRefLeaf(yangInclude.getIncludedNode());
1733 /*
1734 * Update the current reference resolver to external
1735 * module/sub-module containing the referred typedef/grouping.
1736 */
1737 setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
1738
1739 return referredNode;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301740 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1741 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1742 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1743 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301744 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301745
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301746 if (linkedNode != null) {
1747 // Add the link to external entity.
1748 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
1749 /*
1750 * Update the current reference resolver to external
1751 * module/sub-module containing the referred typedef/grouping.
1752 */
1753 setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
1754 // Add the type/uses of referred typedef/grouping to the stack.
1755 addUnresolvedRecursiveReferenceToStack(linkedNode);
1756 return true;
1757 }
1758 }
1759 // If referred node can't be found return false.
1760 return false;
1761 }
1762
1763 /**
1764 * Finds and resolves with import list.
1765 *
1766 * @return true if resolved, false otherwise
1767 * @throws DataModelException a violation in data model rule
1768 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301769 private boolean resolveWithImport()
1770 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301771 /*
1772 * Run through import list to find the referred typedef/grouping.
1773 */
1774 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1775 /*
1776 * Match the prefix attached to entity under resolution with the
1777 * imported/included module/sub-module's prefix. If found, search
1778 * for the referred typedef/grouping at the root level.
1779 */
1780 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1781 YangNode linkedNode = null;
1782 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1783 linkedNode = findRefTypedef(yangImport.getImportedNode());
1784 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1785 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301786 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1787 linkedNode = findRefFeature(yangImport.getImportedNode());
janani be18b5342016-07-13 21:06:41 +05301788 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1789 boolean referredNode = findRefLeaf(yangImport.getImportedNode());
1790 /*
1791 * Update the current reference resolver to external
1792 * module/sub-module containing the referred
1793 * typedef/grouping.
1794 */
1795 setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
1796
1797 return referredNode;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301798 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1799 linkedNode = findRefIdentity(yangImport.getImportedNode());
1800 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1801 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301802 }
1803 if (linkedNode != null) {
1804 // Add the link to external entity.
1805 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
1806 /*
1807 * Update the current reference resolver to external
Bharat saraswal96dfef02016-06-16 00:29:12 +05301808 * module/sub-module containing the referred
1809 * typedef/grouping.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301810 */
1811 setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
Bharat saraswal96dfef02016-06-16 00:29:12 +05301812 // Add the type/uses of referred typedef/grouping to the
1813 // stack.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301814 addUnresolvedRecursiveReferenceToStack(linkedNode);
1815 return true;
1816 }
1817 /*
1818 * If referred node can't be found at root level break for loop,
1819 * and return false.
1820 */
1821 break;
1822 }
1823 }
1824 // If referred node can't be found return false.
1825 return false;
1826 }
1827
1828 /**
janani be18b5342016-07-13 21:06:41 +05301829 * Returns the status of referred leaf.
1830 *
1831 * @param importedNode the root node from a YANG file
1832 * @return status of the referred leaf
1833 * @throws DataModelException
1834 */
1835 private boolean findRefLeaf(YangNode importedNode) throws DataModelException {
1836
1837 boolean isReferredNodeFound = false;
1838 List<YangAtomicPath> absolutePathList = ((YangLeafRef) getCurrentEntityToResolveFromStack())
1839 .getAtomicPath();
1840 if (absolutePathList != null && !absolutePathList.isEmpty()) {
1841 Iterator<YangAtomicPath> listOfYangAtomicPath = absolutePathList.listIterator();
1842
1843 while (listOfYangAtomicPath.hasNext()) {
1844 YangAtomicPath absolutePath = listOfYangAtomicPath.next();
1845 String nodeName = absolutePath.getNodeIdentifier().getName();
1846
1847 if (importedNode.getChild() == null) {
1848 isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode, nodeName, (T) INTER_FILE_LINKED);
1849 break;
1850 }
1851 importedNode = importedNode.getChild();
1852
1853 YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(importedNode, nodeName);
1854 if (nodeFound == null) {
1855 isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode.getParent(), nodeName,
1856 (T) INTER_FILE_LINKED);
1857 } else {
1858 importedNode = nodeFound;
1859 }
1860 }
1861 }
1862 // TODO: Path predicates filling for inter file has to be done.
1863 return isReferredNodeFound;
1864 }
1865
1866 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301867 * Returns referred typedef/grouping node.
1868 *
1869 * @return referred typedef/grouping node
1870 * @throws DataModelException a violation in data model rule
1871 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301872 private T getRefNode()
1873 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301874 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswal96dfef02016-06-16 00:29:12 +05301875 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1876 .getDataTypeExtendedInfo();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301877 return (T) derivedInfo.getReferredTypeDef();
1878 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1879 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301880 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1881 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani be18b5342016-07-13 21:06:41 +05301882 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1883 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301884 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1885 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1886 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1887 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301888 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301889 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
1890 "/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301891 }
1892 }
1893
1894 /**
1895 * Finds the referred grouping node at the root level of imported/included node.
1896 *
1897 * @param refNode module/sub-module node
1898 * @return referred grouping
1899 */
1900 private YangNode findRefGrouping(YangNode refNode) {
1901 YangNode tmpNode = refNode.getChild();
1902 while (tmpNode != null) {
1903 if (tmpNode instanceof YangGrouping) {
1904 if (tmpNode.getName()
1905 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1906 return tmpNode;
1907 }
1908 }
1909 tmpNode = tmpNode.getNextSibling();
1910 }
1911 return null;
1912 }
1913
1914 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301915 * Finds the referred feature node at the root level of imported/included node.
1916 *
1917 * @param refNode module/sub-module node
1918 * @return referred feature
1919 */
1920 private YangNode findRefFeature(YangNode refNode) {
1921 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1922 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1923
1924 if (featureList != null && !featureList.isEmpty()) {
1925 Iterator<YangFeature> iterator = featureList.iterator();
1926 while (iterator.hasNext()) {
1927 YangFeature feature = iterator.next();
1928 if (ifFeature.getName().equals(feature.getName())) {
1929 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1930 return refNode;
1931 }
1932 }
1933 }
1934 return null;
1935 }
1936
1937 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301938 * Finds the referred typedef node at the root level of imported/included node.
1939 *
1940 * @param refNode module/sub-module node
1941 * @return referred typedef
1942 */
1943 private YangNode findRefTypedef(YangNode refNode) {
1944 YangNode tmpNode = refNode.getChild();
1945 while (tmpNode != null) {
1946 if (tmpNode instanceof YangTypeDef) {
1947 if (tmpNode.getName()
1948 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1949 return tmpNode;
1950 }
1951 }
1952 tmpNode = tmpNode.getNextSibling();
1953 }
1954 return null;
1955 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301956
1957 /**
1958 * Finds the referred identity node at the root level of imported/included node.
1959 *
1960 * @param refNode module/sub-module node
1961 * @return referred identity
1962 */
1963 private YangNode findRefIdentity(YangNode refNode) {
1964 YangNode tmpNode = refNode.getChild();
1965 while (tmpNode != null) {
1966 if (tmpNode instanceof YangIdentity) {
1967 if (tmpNode.getName()
1968 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1969 return tmpNode;
1970 }
1971 }
1972 tmpNode = tmpNode.getNextSibling();
1973 }
1974 return null;
1975 }
1976
1977 /**
1978 * Finds the referred identity node at the root level of imported/included node.
1979 *
1980 * @param refNode module/sub-module node
1981 * @return referred identity
1982 */
1983 private YangNode findRefIdentityRef(YangNode refNode) {
1984 YangNode tmpNode = refNode.getChild();
1985 while (tmpNode != null) {
1986 if (tmpNode instanceof YangIdentity) {
1987 if (tmpNode.getName()
1988 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
1989 .getBaseIdentity().getName())) {
1990 return tmpNode;
1991 }
1992 }
1993 tmpNode = tmpNode.getNextSibling();
1994 }
1995 return null;
1996 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301997}