blob: bcc5a5fa6c477b8605052d02aa2b6ef217cc058d [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;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053035import org.onosproject.yangutils.datamodel.YangIfFeature;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053036import org.onosproject.yangutils.datamodel.YangIdentity;
37import org.onosproject.yangutils.datamodel.YangIdentityRef;
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;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053076import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
Vidyashree Rama210c01d2016-05-20 16:29:25 +053077import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +053078import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
79import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053080import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
janani be18b5342016-07-13 21:06:41 +053081import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
82import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
Gaurav Agrawal95b416c2016-06-07 14:00:26 +053083import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +053084import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF_LINKER_ERROR;
85import static org.onosproject.yangutils.utils.UtilConstants.BASE_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 /**
135 * Creates a resolution information object with all the inputs.
136 *
137 * @param dataNode current parsable data node
138 * @param holderNode parent YANG node
139 * @param lineNumber error line number
140 * @param charPositionInLine error character position in line
141 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530142 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
143 setEntityToResolveInfo(new YangEntityToResolveInfoImpl<>());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530144 getEntityToResolveInfo().setEntityToResolve(dataNode);
145 getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
146 this.setLineNumber(lineNumber);
147 this.setCharPosition(charPositionInLine);
148 setPartialResolvedStack(new Stack<>());
149 }
150
Gaurav Agrawal95b416c2016-06-07 14:00:26 +0530151 @Override
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530152 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
153 throws DataModelException {
154
155 setCurReferenceResolver(dataModelRootNode);
156
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530157 /**
158 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
159 * YANG leafref or YANG base or YANG identityref.
160 */
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530161 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
162
163 // Check if linking is already done
164 if (entityToResolve instanceof Resolvable) {
165 Resolvable resolvable = (Resolvable) entityToResolve;
166 if (resolvable.getResolvableStatus() == RESOLVED) {
167 /**
168 * entity is already resolved, so nothing to do
169 */
170 return;
171 }
172 } else {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530173 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530174 "type/uses/if-feature/leafref/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530175 }
176
177 // Push the initial entity to resolve in stack.
178 addInPartialResolvedStack(getEntityToResolveInfo());
179
180 linkAndResolvePartialResolvedStack();
janani be18b5342016-07-13 21:06:41 +0530181
182 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530183 }
184
185 /**
186 * Resolves linking with ancestors.
187 *
188 * @throws DataModelException a violation of data model rules
189 */
190 private void linkAndResolvePartialResolvedStack()
191 throws DataModelException {
192
193 while (getPartialResolvedStack().size() != 0) {
194
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530195 /**
196 * Current node to resolve, it can be a YANG type or YANG uses or
197 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
198 */
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530199 T entityToResolve = getCurrentEntityToResolveFromStack();
200 // Check if linking is already done
201 if (entityToResolve instanceof Resolvable) {
202
203 Resolvable resolvable = (Resolvable) entityToResolve;
204 switch (resolvable.getResolvableStatus()) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530205 case RESOLVED: {
206 /*
207 * If the entity is already resolved in the stack, then pop
208 * it and continue with the remaining stack elements to
209 * resolve
210 */
211 getPartialResolvedStack().pop();
212 break;
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530213 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530214
215 case LINKED: {
216 /*
217 * If the top of the stack is already linked then resolve
218 * the references and pop the entity and continue with
219 * remaining stack elements to resolve.
220 */
221 resolveTopOfStack(INTRA_FILE);
222 getPartialResolvedStack().pop();
223 break;
224 }
225
226 case INTRA_FILE_RESOLVED: {
227 /*
228 * Pop the top of the stack.
229 */
230 getPartialResolvedStack().pop();
231 break;
232 }
233
234 case UNRESOLVED: {
235 linkTopOfStackReferenceUpdateStack();
236
237 if (resolvable.getResolvableStatus() == UNRESOLVED) {
238 // If current entity is still not resolved, then
239 // linking/resolution has failed.
240 String errorInfo;
241 if (resolvable instanceof YangType) {
242 errorInfo = TYPEDEF_LINKER_ERROR;
243 } else if (resolvable instanceof YangUses) {
244 errorInfo = GROUPING_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +0530245 } else if (resolvable instanceof YangIfFeature) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530246 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530247 } else if (resolvable instanceof YangBase) {
248 errorInfo = BASE_LINKER_ERROR;
249 } else if (resolvable instanceof YangIdentityRef) {
250 errorInfo = IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +0530251 } else {
252 errorInfo = LEAFREF_LINKER_ERROR;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530253 }
254 DataModelException dataModelException =
255 new DataModelException(errorInfo);
256 dataModelException.setLine(getLineNumber());
257 dataModelException.setCharPosition(getCharPosition());
258 throw dataModelException;
259 }
260 break;
261 }
262 default: {
263 throw new DataModelException("Data Model Exception: Unsupported, linker state");
264 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530265
266 }
267
268 } else {
janani be18b5342016-07-13 21:06:41 +0530269 throw new DataModelException(
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530270 "Data Model Exception: Entity to resolved is other than type/uses/if-feature" +
271 "/leafref/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530272 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530273 }
274
275 }
276
277 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530278 * Adds the leafref/identityref type to the type, which has derived type referring to
279 * typedef with leafref/identityref type.
janani be18b5342016-07-13 21:06:41 +0530280 */
281 private void addDerivedRefTypeToRefTypeResolutionList() throws DataModelException {
282
283 YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
284
285 // If holder is typedef return.
286 if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
287 return;
288 }
289
290 // If entity is not type return.
291 if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
292 return;
293 }
294
295 YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
296
297 // If type is not resolved return.
298 if (yangType.getResolvableStatus() != RESOLVED) {
299 return;
300 }
301
302 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
303
304 /*
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530305 * If the derived types referred type is not leafref/identityref return
janani be18b5342016-07-13 21:06:41 +0530306 */
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530307 if ((derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) &&
308 (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.IDENTITYREF)) {
janani be18b5342016-07-13 21:06:41 +0530309 return;
310 }
311
312 T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
313
314 while (extendedInfo instanceof YangDerivedInfo) {
315 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
316 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
317 .getDataTypeExtendedInfo();
318 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530319
janani be18b5342016-07-13 21:06:41 +0530320 /*
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530321 * Backup the derived types leafref/identityref info, delete all the info in current type,
322 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
323 * create a leafref/identityref resolution info using the current resolution info and
324 * add to leafref/identityref resolution list.
janani be18b5342016-07-13 21:06:41 +0530325 */
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530326 if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
327 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
328 yangType.resetYangType();
janani be18b5342016-07-13 21:06:41 +0530329
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530330 yangType.setResolvableStatus(RESOLVED);
331 yangType.setDataType(YangDataTypes.LEAFREF);
332 yangType.setDataTypeName(LEAFREF);
333 yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
334 leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
janani be18b5342016-07-13 21:06:41 +0530335
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530336 // Add resolution information to the list.
337 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
338 potentialAncestorWithReferredNode,
339 getLineNumber(), getCharPosition());
340 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
341 ResolvableType.YANG_LEAFREF);
342 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
343
344 } else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
345
346 YangIdentityRef identityRefInTypeDef = (YangIdentityRef) extendedInfo;
347 yangType.resetYangType();
348
349 yangType.setResolvableStatus(RESOLVED);
350 yangType.setDataType(YangDataTypes.IDENTITYREF);
351 yangType.setDataTypeName(IDENTITYREF);
352 yangType.setDataTypeExtendedInfo(identityRefInTypeDef);
353 identityRefInTypeDef.setResolvableStatus(UNRESOLVED);
354
355 // Add resolution information to the list.
356 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
357 potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
358 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
359 ResolvableType.YANG_IDENTITYREF);
360 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
361 }
janani be18b5342016-07-13 21:06:41 +0530362 }
363
364 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530365 * Resolves the current entity in the stack.
366 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530367 private void resolveTopOfStack(YangLinkingPhase linkingPhase)
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530368 throws DataModelException {
369 ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530370 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
371 && ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
janani be18b5342016-07-13 21:06:41 +0530372 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530373 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
374 }
375 }
376
377 /**
378 * Resolves linking for a node child and siblings.
379 *
380 * @throws DataModelException data model error
381 */
382 private void linkTopOfStackReferenceUpdateStack()
383 throws DataModelException {
384
385 /*
386 * Check if self file reference is there, this will not check for the
387 * scenario when prefix is not present and type/uses is present in
388 * sub-module from include list.
389 */
390 if (!isCandidateForSelfFileReference()) {
391 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
392 return;
393 }
394
395 /**
396 * Try to resolve the top of the stack and update partial resolved stack
397 * if there is recursive references
398 */
399 YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
400 .getHolderOfEntityToResolve();
401
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530402 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
403 resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
404 return;
janani be18b5342016-07-13 21:06:41 +0530405 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
406 resolveSelfFileLinkingForLeafref(potentialAncestorWithReferredNode);
407 return;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530408 } else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
409 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
410 resolveSelfFileLinkingForBaseAndIdentityref();
411 return;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530412 } else {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530413
414 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530415 * Traverse up in the ancestor tree to check if the referred node is
416 * defined
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530417 */
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530418 while (potentialAncestorWithReferredNode != null) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530419
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530420 /**
421 * Check for the referred node defined in a ancestor scope
422 */
423 YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
424 if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
425 return;
426 }
427
428 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
429 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530430 }
431
432 /*
433 * In case prefix is not present it's a candidate for inter-file
434 * resolution via include list.
435 */
436 if (getRefPrefix() == null) {
437 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
438 }
439 }
440
441 /**
janani be18b5342016-07-13 21:06:41 +0530442 * Resolves self file linking for leafref.
443 *
444 * @param potentialAncestorWithReferredNode leafref holder node
445 * @throws DataModelException a violation of data model rules
446 */
447 private void resolveSelfFileLinkingForLeafref(YangNode potentialAncestorWithReferredNode)
448 throws DataModelException {
449
450 YangNode ancestorWithTheReferredNode = potentialAncestorWithReferredNode;
451 YangLeafRef leafref = (YangLeafRef) getCurrentEntityToResolveFromStack();
452 boolean referredLeafFound = false;
453
454 /*
455 * Takes absolute path and takes the root node as module/sub-module,
456 * then sends the list of nodes for finding the target leaf.
457 */
458 if (leafref.getPathType() == YangPathArgType.ABSOLUTE_PATH) {
459 List<YangAtomicPath> atomicPathList = leafref.getAtomicPath();
460 if (atomicPathList != null && !atomicPathList.isEmpty()) {
461 Iterator<YangAtomicPath> listOfYangAtomicPath = atomicPathList.listIterator();
462 if (getCurReferenceResolver() instanceof YangModule) {
463 YangModule rootNode = (YangModule) getCurReferenceResolver();
464 // Sends list of nodes for finding the target leaf.
465 referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
466 referredLeafFound, potentialAncestorWithReferredNode);
467 } else if (getCurReferenceResolver() instanceof YangSubModule) {
468 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
469 // Sends list of nodes for finding the target leaf.
470 referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
471 referredLeafFound, potentialAncestorWithReferredNode);
472 }
473 }
474 /*
475 * Takes relative path, goes to the parent node by using the
476 * ancestor count and sends the list of nodes for finding the target
477 * leaf.
478 */
479 } else if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
480 YangRelativePath yangRelativePath = leafref.getRelativePath();
481 int parentNodes = yangRelativePath.getAncestorNodeCount();
482 List<YangAtomicPath> atomicPathList = yangRelativePath.getAtomicPathList();
483 if (atomicPathList != null && !atomicPathList.isEmpty()) {
484 Iterator<YangAtomicPath> listOfAtomicPath = atomicPathList.listIterator();
485 // Gets the root node from ancestor count.
486 YangNode rootparentNode = getRootNodeWithAncestorCount(parentNodes, ancestorWithTheReferredNode);
487 // Sends list of nodes for finding the target leaf.
488 referredLeafFound = isLeafReferenceFound(listOfAtomicPath, rootparentNode,
489 referredLeafFound, potentialAncestorWithReferredNode);
490 }
491 }
492 if (referredLeafFound) {
493 return;
494 }
495 /*
496 * In case prefix is not present it's a candidate for inter-file
497 * resolution via include list.
498 */
499 if (getRefPrefix() == null) {
500 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
501 }
502 }
503
504 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530505 * Resolves self file linking for base/identityref.
506 *
507 * @throws DataModelException a violation of data model rules
508 */
509 private void resolveSelfFileLinkingForBaseAndIdentityref()
510 throws DataModelException {
511
512 boolean referredIdentityFound = false;
513 String nodeName = null;
514
515 if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
516 nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
517 }
518
519 if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
520 nodeName = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName();
521 }
522
523 if (getCurReferenceResolver() instanceof YangModule) {
524 YangModule rootNode = (YangModule) getCurReferenceResolver();
525 // Sends list of nodes for finding the target identity.
526 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
527 } else if (getCurReferenceResolver() instanceof YangSubModule) {
528 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
529 // Sends list of nodes for finding the target identity.
530 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
531 }
532
533 if (referredIdentityFound) {
534 return;
535 }
536
537 /*
538 * In case prefix is not present it's a candidate for inter-file resolution via include list.
539 */
540 if (getRefPrefix() == null) {
541 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
542 }
543 }
544
545 /**
janani be18b5342016-07-13 21:06:41 +0530546 * Returns the root parent with respect to the ancestor count from leafref.
547 *
548 * @param ancestorCount count of node where parent node can be reached
549 * @param currentParent current parent node
550 * @return root node
551 * @throws DataModelException a violation of data model rules
552 */
553 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
554 throws DataModelException {
555
556 int currentParentCount = 1;
557 while (currentParentCount < ancestorCount) {
558 if (currentParent.getParent() == null) {
559 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
560 }
561 currentParent = currentParent.getParent();
562 currentParentCount = currentParentCount + 1;
563 }
564 return currentParent;
565 }
566
567 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530568 * Resolves self file linking for if-feature.
569 *
570 * @param potentialAncestorWithReferredNode if-feature holder node
571 * @throws DataModelException DataModelException a violation of data model
572 * rules
573 */
574 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
575 throws DataModelException {
576
577 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
578 YangNode potentialReferredNode = (YangNode) featureHolder;
579 if (isReferredNode(potentialReferredNode)) {
580
581 // Adds reference link of entity to the node under resolution.
582 addReferredEntityLink(potentialReferredNode, LINKED);
583
584 /**
585 * resolve the reference and update the partial resolution stack
586 * with any further recursive references
587 */
588 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
589 return;
590 }
591
592 /*
593 * In case prefix is not present it's a candidate for inter-file
594 * resolution via include list.
595 */
596 if (getRefPrefix() == null) {
597 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
598 }
599 }
600
janani be18b5342016-07-13 21:06:41 +0530601 /**
602 * Returns the status of the referred leaf/leaf-list found for leafref.
603 *
604 * @param listOfYangAtomicPath list of atomic paths
605 * @param ancestorWithTheReferredNode the parent node of leafref
606 * @param referredLeafFound status of referred leaf/leaf-list
607 * @param potentialAncestorWithReferredNode holder of the leafref leaf
608 * @return status of referred leaf
609 * @throws DataModelException a violation of data model rules
610 */
611 private boolean isLeafReferenceFound(Iterator<YangAtomicPath> listOfYangAtomicPath,
612 YangNode ancestorWithTheReferredNode, boolean referredLeafFound, YangNode potentialAncestorWithReferredNode)
613 throws DataModelException {
614
615 while (listOfYangAtomicPath.hasNext()) {
616 YangAtomicPath atomicPath = listOfYangAtomicPath.next();
617 String nodeName = atomicPath.getNodeIdentifier().getName();
618
619 // When child is not present, only leaf/leaf-list is available in the node.
620 if (ancestorWithTheReferredNode.getChild() == null) {
621 referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode, nodeName, (T) LINKED);
622 break;
623 }
624 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
625
626 // Checks all the siblings under the node and returns the matched node.
627 YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(ancestorWithTheReferredNode, nodeName);
628
629 // When node is not found in all the siblings, leaf-list may be the node we have to find.
630 if (nodeFound == null) {
631 referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode.getParent(), nodeName,
632 (T) LINKED);
633 } else {
634 ancestorWithTheReferredNode = nodeFound;
635
636 // For the node check if path predicate is present and fill its values.
637 List<YangPathPredicate> pathPredicateList = atomicPath.getPathPredicatesList();
638 if (pathPredicateList != null && !pathPredicateList.isEmpty()) {
639 Iterator<YangPathPredicate> listOfYangPathPredicate = pathPredicateList.listIterator();
640 fillPathPredicatesForTheNode(ancestorWithTheReferredNode, listOfYangPathPredicate,
641 potentialAncestorWithReferredNode);
642 }
643 }
644
645 // If leaf is also not found and node is also not found return the status as false.
646 if (!referredLeafFound && nodeFound == null) {
647 break;
648 }
649 }
650 return referredLeafFound;
651 }
652
653 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530654 * Returns the status of the referred identity found for base/identityref.
655 *
656 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
657 * @param ancestorWithTheReferredNode the parent node of base/identityref
658 * @return status of referred base/identityref
659 * @throws DataModelException a violation of data model rules
660 */
661 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
662 throws DataModelException {
663
664 // When child is not present return.
665 if (ancestorWithTheReferredNode.getChild() == null) {
666 return false;
667 }
668
669 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
670
671 // Checks all the siblings under the node and returns the matched node.
672 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
673
674 if (nodeFound != null) {
675 // Adds reference link of entity to the node under resolution.
676 addReferredEntityLink(nodeFound, LINKED);
677
678 /**
679 * resolve the reference and update the partial resolution stack with any further recursive references
680 */
681 addUnresolvedRecursiveReferenceToStack(nodeFound);
682 return true;
683 }
684
685 return false;
686 }
687
688 /**
janani be18b5342016-07-13 21:06:41 +0530689 * Fills the referred leaf or leaf-list inside the path predicates.
690 *
691 * @param ancestorWithTheReferredNode the actual node where YANG list will be present
692 * @param listOfYangPathPredicate the path predicates present for the node
693 * @param potentialAncestorWithReferredNode the current leaf node parent
694 * @throws DataModelException a violation of data model rules
695 */
696 private void fillPathPredicatesForTheNode(YangNode ancestorWithTheReferredNode,
697 Iterator<YangPathPredicate> listOfYangPathPredicate, YangNode potentialAncestorWithReferredNode)
698 throws DataModelException {
699
700 while (listOfYangPathPredicate.hasNext()) {
701 if (!(ancestorWithTheReferredNode instanceof YangList)) {
702 throw new DataModelException("YANG file error: The path predicates are applicable only for list");
703 }
704 YangPathPredicate pathPredicate = listOfYangPathPredicate.next();
705 YangNodeIdentifier leftNode = pathPredicate.getNodeIdentifier();
706 YangRelativePath relativePath = pathPredicate.getRightRelativePath();
707
708 // Checks that the left axis is filled in the path predicate.
709 boolean isLeftLeafOrLeafListSetForLeftAxis = getLeftLeafOrLeafListInPredicate(
710 (YangList) ancestorWithTheReferredNode, pathPredicate, leftNode);
711 if (!isLeftLeafOrLeafListSetForLeftAxis) {
712 throw new DataModelException(
713 "YANG file error: The path predicate is not referring to an existing leaf/leaflist");
714 }
715 int parentNodes = relativePath.getAncestorNodeCount();
716
717 // Finds the root node for the right relative path.
718 YangNode rootParentNode = getRootNodeWithAncestorCount(parentNodes, potentialAncestorWithReferredNode);
719
720 // Finds the leaf/leaf-list from the right side relative path.
721 resolveRightAxisNodeInPathPredicate(relativePath, rootParentNode, pathPredicate);
722 }
723 }
724
725 /**
726 * Resolves the right axis node in the path predicate.
727 *
728 * @param relativePath the relative path in the path predicate
729 * @param rootParentNode parent node from where the node has to be found
730 * @param pathPredicate data tree reference in YANG list
731 * @throws DataModelException a violation of data model rules
732 */
733 private void resolveRightAxisNodeInPathPredicate(YangRelativePath relativePath, YangNode rootParentNode,
734 YangPathPredicate pathPredicate) throws DataModelException {
735
736 List<YangAtomicPath> absolutePathList = relativePath.getAtomicPathList();
737 if (absolutePathList != null && !absolutePathList.isEmpty()) {
738 Iterator<YangAtomicPath> listOfYangAtomicPathForRightRelative = absolutePathList.listIterator();
739 while (listOfYangAtomicPathForRightRelative.hasNext()) {
740 boolean isRightAxisNodeFound = false;
741 YangAtomicPath absolutePathInPredicate = listOfYangAtomicPathForRightRelative.next();
742 String nodeNameInAtomicPath = absolutePathInPredicate.getNodeIdentifier().getName();
743
744 // When child is not there check the leaf/leaf-list.
745 if (rootParentNode.getChild() == null) {
746 isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode,
747 nodeNameInAtomicPath, (T) pathPredicate);
748 if (!isRightAxisNodeFound) {
749 throw new DataModelException(
750 "YANG file error: The path predicates is not referring to an existing leaf/leaflist");
751 }
752 break;
753 }
754 rootParentNode = rootParentNode.getChild();
755 YangNode nodeFoundInTheRelativePath = isReferredNodeInSiblingProcessedForLeafref(
756 rootParentNode, nodeNameInAtomicPath);
757
758 if (nodeFoundInTheRelativePath == null) {
759
760 // When node is not found check the leaf/leaf-list.
761 isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode.getParent(),
762 nodeNameInAtomicPath, (T) pathPredicate);
763 } else {
764 rootParentNode = nodeFoundInTheRelativePath;
765 }
766 if (!isRightAxisNodeFound && nodeFoundInTheRelativePath == null) {
767 throw new DataModelException(
768 "YANG file error: The path predicates is not referring to an existing leaf/leaflist");
769 }
770 }
771 }
772 }
773
774 /**
775 * Returns the status, if referred leaf/leaf-list is found.
776 *
777 * @param ancestorWithTheReferredNode the parent node of leaf/leaf-list
778 * @param nodeName the name of the leaf/leaf-list
779 * @param statusOrPathPredicate the status to be set for the leaf-ref or the path predicate
780 * @return status of the target node is found
781 * @throws DataModelException a violation of data model rules
782 */
783 private boolean isReferredLeafOrLeafListFound(YangNode ancestorWithTheReferredNode, String nodeName,
784 T statusOrPathPredicate) throws DataModelException {
785
786 if (!(ancestorWithTheReferredNode instanceof YangLeavesHolder)) {
787 throw new DataModelException("Yang file error: The target node of leafref is invalid.");
788 }
789 YangLeavesHolder leavesHolder = (YangLeavesHolder) ancestorWithTheReferredNode;
790 if (leavesHolder.getListOfLeaf() != null) {
791 Iterator<YangLeaf> yangLeavesList = leavesHolder.getListOfLeaf().listIterator();
792 while (yangLeavesList.hasNext()) {
793 YangLeaf yangleaf = yangLeavesList.next();
794 if (yangleaf.getName().contentEquals(nodeName)) {
795 if (statusOrPathPredicate instanceof ResolvableStatus) {
796 ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
797
798 // Sets the referred leaf to YANG leafref.
799 ((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangleaf);
800
801 // Adds reference link of entity to the node under resolution.
802 addReferredEntityLink(ancestorWithTheReferredNode, status);
803 addUnResolvedLeafRefTypeToStack((T) yangleaf, ancestorWithTheReferredNode);
804 return true;
805 } else if (statusOrPathPredicate instanceof YangPathPredicate) {
806 YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
807
808 // Sets the right axis node.
809 pathPredicate.setRightAxisNode(yangleaf);
810 return true;
811 } else {
812 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
813 }
814 }
815 }
816 }
817 if (leavesHolder.getListOfLeafList() != null) {
818 Iterator<YangLeafList> yangLeafListList = leavesHolder.getListOfLeafList().listIterator();
819 while (yangLeafListList.hasNext()) {
820 YangLeafList yangLeaflist = yangLeafListList.next();
821 if (yangLeaflist.getName().contentEquals(nodeName)) {
822 if (statusOrPathPredicate instanceof ResolvableStatus) {
823 ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
824
825 // Sets the referred leaf-list to YANG leafref.
826 ((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangLeaflist);
827
828 // Adds reference link of entity to the node under resolution.
829 addReferredEntityLink(ancestorWithTheReferredNode, status);
830 addUnResolvedLeafRefTypeToStack((T) yangLeaflist, ancestorWithTheReferredNode);
831 return true;
832 } else if (statusOrPathPredicate instanceof YangPathPredicate) {
833 YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
834 pathPredicate.setRightAxisNode(yangLeaflist);
835 return true;
836 } else {
837 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
838 }
839 }
840 }
841 }
842 return false;
843 }
844
845 /**
846 * Adds the unresolved constructs to stack which has to be resolved for leafref.
847 *
848 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
849 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
850 */
851 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
852
853 YangType referredTypeInLeafOrLeafList;
854 if (yangleafOrLeafList instanceof YangLeaf) {
855 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
856 referredTypeInLeafOrLeafList = leaf.getDataType();
857 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
858 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
859 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
860 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
861 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
862 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
863 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
864 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
865 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
866 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
867 }
868 } else {
869 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
870 referredTypeInLeafOrLeafList = leafList.getDataType();
871 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
872 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
873 unResolvedEntityInfo
874 .setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
875 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
876 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
877 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
878 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
879 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
880 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
881 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
882 }
883 }
884 }
885
886 /**
887 * Returns true if referred leaf/leaf-list is found in a particular node. This is for path in path predicate.
888 *
889 * @param listForLeaf list node where referred leaf is found
890 * @param pathPredicate path predicate instance where the value of nodes to be found are available
891 * @param leftNode node identifier of the left side parameter in path predicate
892 * @return status of the leaf/leaf-list found
893 */
894 private boolean getLeftLeafOrLeafListInPredicate(YangList listForLeaf, YangPathPredicate pathPredicate,
895 YangNodeIdentifier leftNode) {
896
897 if (listForLeaf.getListOfLeaf() != null) {
898 Iterator<YangLeaf> yangLeavesUnderList = listForLeaf.getListOfLeaf().listIterator();
899 while (yangLeavesUnderList.hasNext()) {
900 YangLeaf yangleafUnderList = yangLeavesUnderList.next();
901 if (yangleafUnderList.getName().contentEquals(leftNode.getName())) {
902 pathPredicate.setLeftAxisNode(yangleafUnderList);
903 return true;
904 }
905 }
906 }
907 if (listForLeaf.getListOfLeafList() != null) {
908 Iterator<YangLeafList> yangLeavesListUnderList = listForLeaf.getListOfLeafList().listIterator();
909 while (yangLeavesListUnderList.hasNext()) {
910 YangLeafList yangleafListUnderList = yangLeavesListUnderList.next();
911 if (yangleafListUnderList.getName().contentEquals(leftNode.getName())) {
912 pathPredicate.setLeftAxisNode(yangleafListUnderList);
913 return true;
914 }
915 }
916 }
917 return false;
918 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530919
920 /**
921 * Returns feature holder(module/sub-module node) .
922 *
923 * @param potentialAncestorWithReferredNode if-feature holder node
924 */
925 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
926 while (potentialAncestorWithReferredNode != null) {
927 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
928 return (YangFeatureHolder) potentialAncestorWithReferredNode;
929 }
930 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
931 }
932 return null;
933 }
934
935 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530936 * Checks if the reference in self file or in external file.
937 *
938 * @return true if self file reference, false otherwise
939 * @throws DataModelException a violation of data model rules
940 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530941 private boolean isCandidateForSelfFileReference()
942 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +0530943 String prefix = getRefPrefix();
944 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
945 }
946
947 /**
janani be18b5342016-07-13 21:06:41 +0530948 * Checks for the referred parent node for the leafref path.
949 *
950 * @param potentialReferredNode potential referred node
951 * @return the reffered parent node of leaf/leaf-list
952 * @throws DataModelException data model errors
953 */
954 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
955 throws DataModelException {
956
957 while (potentialReferredNode != null) {
958 if (potentialReferredNode instanceof YangInput) {
959 if (referredNodeName.equalsIgnoreCase(INPUT)) {
960 return potentialReferredNode;
961 }
962 } else if (potentialReferredNode instanceof YangOutput) {
963 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
964 return potentialReferredNode;
965 }
966 }
967 // Check if the potential referred node is the actual referred node
968 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
969 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
970 if (potentialReferredNode.getParent() instanceof YangRpc) {
971 potentialReferredNode = potentialReferredNode.getNextSibling();
972 } else {
973 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
974 }
975 }
976 return potentialReferredNode;
977 }
978 potentialReferredNode = potentialReferredNode.getNextSibling();
979 }
980 return null;
981 }
982
983 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +0530984 * Checks for the referred parent node for the base/identity.
985 *
986 * @param potentialReferredNode potential referred node
987 * @return the reffered parent node of base/identity.
988 * @throws DataModelException data model errors
989 */
990 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
991 String referredNodeName) throws DataModelException {
992
993 while (potentialReferredNode != null) {
994 if (potentialReferredNode instanceof YangIdentity) {
995 // Check if the potential referred node is the actual referred node
996 if (isReferredNodeForIdentity(potentialReferredNode, referredNodeName)) {
997 return potentialReferredNode;
998 }
999 }
1000 potentialReferredNode = potentialReferredNode.getNextSibling();
1001 }
1002 return null;
1003 }
1004
1005 /**
janani be18b5342016-07-13 21:06:41 +05301006 * Checks if the current reference node name and the name in the path are equal.
1007 *
1008 * @param currentReferredNode the node where the reference is pointed
1009 * @param nameOfNodeinPath name of the node in the path
1010 * @return status of the match between the name
1011 * @throws DataModelException a violation of data model rules
1012 */
1013 private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
1014 throws DataModelException {
1015
1016 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1017 /*
1018 * Check if name of node name matches with the current reference
1019 * node.
1020 */
1021 return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
1022 } else {
1023 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
1024 }
1025 }
1026
1027 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301028 * Checks if the current reference node name and the name in the base/identityref base are equal.
1029 *
1030 * @param currentReferredNode the node where the reference is pointed
1031 * @param nameOfIdentityRefBase name of the base in the base/identityref base
1032 * @return status of the match between the name
1033 * @throws DataModelException a violation of data model rules
1034 */
1035 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
1036 throws DataModelException {
1037
1038 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
1039 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
1040 /*
1041 * Check if name of node name matches with the current reference node.
1042 */
1043 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
1044 } else {
1045 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref");
1046 }
1047 }
1048
1049 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301050 * Checks for the referred node defined in a ancestor scope.
1051 *
1052 * @param potentialReferredNode potential referred node
1053 * @return status of resolution and updating the partial resolved stack with
1054 * the any recursive references
janani be18b5342016-07-13 21:06:41 +05301055 * @throws DataModelException a violation of data model rules
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301056 */
1057 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
1058 throws DataModelException {
1059 while (potentialReferredNode != null) {
1060
1061 // Check if the potential referred node is the actual referred node
1062 if (isReferredNode(potentialReferredNode)) {
1063
1064 // Adds reference link of entity to the node under resolution.
1065 addReferredEntityLink(potentialReferredNode, LINKED);
1066
1067 /**
1068 * resolve the reference and update the partial resolution stack
1069 * with any further recursive references
1070 */
1071 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
1072
1073 /*
1074 * return true, since the reference is linked and any recursive
1075 * unresolved references is added to the stack
1076 */
1077 return true;
1078 }
1079
1080 potentialReferredNode = potentialReferredNode.getNextSibling();
1081 }
1082 return false;
1083 }
1084
1085 /**
1086 * Checks if the potential referred node is the actual referred node.
1087 *
1088 * @param potentialReferredNode typedef/grouping node
1089 * @return true if node is of resolve type otherwise false
1090 * @throws DataModelException a violation of data model rules
1091 */
1092 private boolean isReferredNode(YangNode potentialReferredNode)
1093 throws DataModelException {
1094 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1095 if (potentialReferredNode instanceof YangTypeDef) {
1096 /*
1097 * Check if name of node name matches with the entity being
1098 * resolved
1099 */
1100 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1101 }
1102 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1103 if (potentialReferredNode instanceof YangGrouping) {
1104 /*
1105 * Check if name of node name matches with the entity being
1106 * resolved
1107 */
1108 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1109 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301110 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1111 if (potentialReferredNode instanceof YangFeatureHolder) {
1112 /*
1113 * Check if name of node name matches with the entity being
1114 * resolved
1115 */
1116 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1117 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301118 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1119 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
1120 if (potentialReferredNode instanceof YangIdentity) {
1121 /*
1122 * Check if name of node name matches with the entity being
1123 * resolved
1124 */
1125 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
1126 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301127 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301128 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
1129 "uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301130 }
1131 return false;
1132 }
1133
1134 /**
1135 * Checks if node name is same as name in resolution info, i.e. name of
1136 * typedef/grouping is same as name of type/uses.
1137 *
1138 * @param node typedef/grouping node
1139 * @return true if node name is same as name in resolution info, otherwise
1140 * false
1141 * @throws DataModelException a violation of data model rules
1142 */
1143
1144 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
1145 throws DataModelException {
1146 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1147 if (node.getName().contentEquals(
1148 ((YangType<?>) getCurrentEntityToResolveFromStack())
1149 .getDataTypeName())) {
1150 return true;
1151 }
1152 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1153 if (node.getName().contentEquals(
1154 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1155 return true;
1156 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301157 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1158 return isFeatureDefinedInNode(node);
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301159 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1160 if (node.getName().contentEquals(
1161 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1162 return true;
1163 }
1164 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1165 if (node.getName().contentEquals(
1166 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
1167 return true;
1168 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301169 } else {
1170 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1171 }
1172 return false;
1173 }
1174
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301175 private boolean isFeatureDefinedInNode(YangNode node) throws DataModelException {
1176 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1177 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
1178 if (featureList != null && !featureList.isEmpty()) {
1179 Iterator<YangFeature> iterator = featureList.iterator();
1180 while (iterator.hasNext()) {
1181 YangFeature feature = iterator.next();
1182 if (ifFeature.getName().equals(feature.getName())) {
1183 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1184 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
1185 return true;
1186 }
1187 }
1188 }
1189 return false;
1190 }
1191
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301192 /**
1193 * Adds reference of grouping/typedef in uses/type.
1194 *
1195 * @param referredNode grouping/typedef node being referred
1196 * @param linkedStatus linked status if success.
1197 * @throws DataModelException a violation of data model rules
1198 */
1199 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
1200 throws DataModelException {
1201 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswal96dfef02016-06-16 00:29:12 +05301202 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1203 .getDataTypeExtendedInfo();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301204 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
1205 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1206 ((YangUses) getCurrentEntityToResolveFromStack())
1207 .setRefGroup((YangGrouping) referredNode);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301208 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1209 // do nothing , referred node is already set
janani be18b5342016-07-13 21:06:41 +05301210 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1211 // do nothing , referred node is already set
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301212 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1213 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
1214 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1215 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301216 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301217 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
1218 "/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301219 }
1220
1221 // Sets the resolution status in inside the type/uses.
1222 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
1223 }
1224
1225 /**
1226 * Checks if type/grouping has further reference to typedef/ unresolved
1227 * uses. Add it to the partial resolve stack and return the status of
1228 * addition to stack.
1229 *
1230 * @param referredNode grouping/typedef node
1231 * @throws DataModelException a violation of data model rules
1232 */
1233 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
1234 throws DataModelException {
1235 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1236 /*
1237 * Checks if typedef type is derived
1238 */
Bharat saraswal96dfef02016-06-16 00:29:12 +05301239 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301240
Bharat saraswal96dfef02016-06-16 00:29:12 +05301241 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301242 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
1243 .getTypeDefBaseType());
1244 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301245 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301246 }
1247
1248 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1249 /*
1250 * Search if the grouping has any un resolved uses child, if so
1251 * return true, else return false.
1252 */
1253 addUnResolvedUsesToStack(referredNode);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301254 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1255 addUnResolvedIfFeatureToStack(referredNode);
janani be18b5342016-07-13 21:06:41 +05301256 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1257 // do nothing , referred node is already set
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301258 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301259 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1260 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
1261 /*
1262 * Search if the identity has any un resolved base, if so return true, else return false.
1263 */
1264 addUnResolvedBaseToStack(referredNode);
1265 } else {
1266 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
1267 "base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301268 }
1269 }
1270
1271 /**
1272 * Returns if there is any unresolved uses in grouping.
1273 *
1274 * @param node grouping/typedef node
1275 */
1276 private void addUnResolvedUsesToStack(YangNode node) {
1277
1278 /**
1279 * Search the grouping node's children for presence of uses node.
1280 */
1281 YangNode curNode = node.getChild();
1282 while (curNode != null) {
1283 if (curNode instanceof YangUses) {
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301284 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301285 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1286 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301287 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301288
1289 }
1290 curNode = curNode.getNextSibling();
1291 }
1292 }
1293
1294 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301295 * Returns if there is any unresolved if-feature in feature.
1296 *
1297 * @param node module/submodule node
1298 */
1299 private void addUnResolvedIfFeatureToStack(YangNode node) {
1300 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1301 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1302 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1303 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1304 while (ifFeatureIterator.hasNext()) {
1305 YangIfFeature ifFeature = ifFeatureIterator.next();
1306 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1307 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1308 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1309 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1310 }
1311 }
1312 }
1313
1314 /**
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301315 * Returns if there is any unresolved base in identity.
1316 *
1317 * @param node module/submodule node
1318 */
1319 private void addUnResolvedBaseToStack(YangNode node) {
1320
1321 YangIdentity curNode = (YangIdentity) node;
1322 if (curNode.getBaseNode() != null) {
1323 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1324 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1325 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1326 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1327 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1328
1329 }
1330 }
1331 }
1332
1333
1334 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301335 * Returns stack of YANG type with partially resolved YANG construct
1336 * hierarchy.
1337 *
1338 * @return partial resolved YANG construct stack
1339 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301340 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301341 return partialResolvedStack;
1342 }
1343
1344 /**
1345 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1346 *
1347 * @param partialResolvedStack partial resolved YANG construct stack
1348 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301349 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301350 this.partialResolvedStack = partialResolvedStack;
1351 }
1352
1353 /**
1354 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1355 *
1356 * @param partialResolvedInfo partial resolved YANG construct stack
1357 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301358 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301359 getPartialResolvedStack().push(partialResolvedInfo);
1360 }
1361
1362 /**
1363 * Retrieves the next entity in the stack that needs to be resolved. It is
1364 * assumed that the caller ensures that the stack is not empty.
1365 *
1366 * @return next entity in the stack that needs to be resolved
1367 */
1368 private T getCurrentEntityToResolveFromStack() {
1369 return getPartialResolvedStack().peek().getEntityToResolve();
1370 }
1371
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301372 @Override
1373 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301374 return entityToResolveInfo;
1375 }
1376
1377 /**
1378 * Sets information about the entity that needs to be resolved.
1379 *
1380 * @param entityToResolveInfo information about the entity that needs to be
1381 * resolved
1382 */
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301383 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301384 this.entityToResolveInfo = entityToResolveInfo;
1385 }
1386
1387 @Override
1388 public int getLineNumber() {
1389 return lineNumber;
1390 }
1391
1392 @Override
1393 public int getCharPosition() {
1394 return charPosition;
1395 }
1396
1397 @Override
1398 public void setLineNumber(int lineNumber) {
1399 this.lineNumber = lineNumber;
1400 }
1401
1402 @Override
1403 public void setCharPosition(int charPositionInLine) {
1404 this.charPosition = charPositionInLine;
1405 }
1406
1407 /**
1408 * Returns current module/sub-module reference, will be used in inter-file/
1409 * inter-jar scenario to get the import/include list.
1410 *
1411 * @return current module/sub-module reference
1412 */
1413 private YangReferenceResolver getCurReferenceResolver() {
1414 return curReferenceResolver;
1415 }
1416
1417 /**
1418 * Sets current module/sub-module reference, will be used in inter-file/
1419 * inter-jar scenario to get the import/include list.
1420 *
1421 * @param curReferenceResolver current module/sub-module reference
1422 */
1423 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1424 this.curReferenceResolver = curReferenceResolver;
1425 }
1426
Gaurav Agrawal95b416c2016-06-07 14:00:26 +05301427 @Override
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301428 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1429 throws DataModelException {
1430
1431 setCurReferenceResolver(dataModelRootNode);
1432
1433 // Current node to resolve, it can be a YANG type or YANG uses.
1434 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1435
1436 // Check if linking is already done
1437 if (entityToResolve instanceof Resolvable) {
1438 Resolvable resolvable = (Resolvable) entityToResolve;
1439 if (resolvable.getResolvableStatus() == RESOLVED) {
1440 return;
1441 }
1442 } else {
1443 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1444 }
1445
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301446 if (entityToResolve instanceof YangXPathResolver) {
1447 //Process x-path linking.
1448 processXPathLinking(getEntityToResolveInfo(), dataModelRootNode);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301449
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301450 } else {
janani be18b5342016-07-13 21:06:41 +05301451
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301452 // Push the initial entity to resolve in stack.
1453 addInPartialResolvedStack(getEntityToResolveInfo());
1454
1455 // Inter file linking and resolution.
1456 linkInterFileAndResolve();
1457
1458 addDerivedRefTypeToRefTypeResolutionList();
1459 }
1460 }
1461
1462 /**
1463 * Process x-path linking for augment and leaf-ref.
1464 *
1465 * @param entityToResolveInfo entity to resolve
1466 * @param root root node
1467 */
1468 private void processXPathLinking(YangEntityToResolveInfoImpl<T> entityToResolveInfo,
1469 YangReferenceResolver root) {
1470 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
1471 T entityToResolve = entityToResolveInfo.getEntityToResolve();
1472 if (entityToResolve instanceof YangAugment) {
1473 YangNode targetNode = null;
1474 YangAugment augment = (YangAugment) entityToResolve;
1475 targetNode = xPathLinker.processAugmentXpathLinking(augment.getTargetNode(),
1476 (YangNode) root);
1477 if (targetNode != null) {
1478 if (targetNode instanceof YangAugmentableNode) {
1479 detectCollisionForAugmentedNode(targetNode, augment);
1480 ((YangAugmentableNode) targetNode).addAugmentation(augment);
1481 augment.setAugmentedNode(targetNode);
1482 Resolvable resolvable = (Resolvable) entityToResolve;
1483 resolvable.setResolvableStatus(RESOLVED);
1484 } else {
1485 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for "
1486 + augment.getName());
1487 }
1488 } else {
1489 throw new LinkerException("Failed to link " + augment.getName());
1490 }
1491 } else if (entityToResolve instanceof YangLeafRef) {
1492 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
1493 Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
1494 (YangNode) root);
1495 if (target != null) {
1496 YangLeaf leaf = null;
1497 YangLeafList leafList = null;
1498 leafRef.setReferredLeafOrLeafList(target);
1499 if (target instanceof YangLeaf) {
1500 leaf = (YangLeaf) target;
1501 leafRef.setEffectiveDataType(leaf.getDataType());
1502 } else {
1503 leafList = (YangLeafList) target;
1504 leafRef.setEffectiveDataType(leafList.getDataType());
1505 }
1506 leafRef.setResolvableStatus(RESOLVED);
1507 //TODO: add logic for leaf-ref for path predicates.
1508 } else {
1509 throw new LinkerException("YANG file error: Unable to find base leaf/leaf-list for given leafref "
1510 + leafRef.getPath());
1511 }
1512 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301513 }
1514
1515 /**
1516 * Returns the referenced prefix of entity under resolution.
1517 *
1518 * @return referenced prefix of entity under resolution
1519 * @throws DataModelException a violation in data model rule
1520 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301521 private String getRefPrefix()
1522 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301523 String refPrefix;
1524 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1525 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1526 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1527 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301528 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1529 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
janani be18b5342016-07-13 21:06:41 +05301530 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1531 refPrefix = refPrefixForLeafRef();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301532 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1533 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1534 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1535 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301536 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301537 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
1538 "type/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301539 }
1540 return refPrefix;
1541 }
1542
1543 /**
janani be18b5342016-07-13 21:06:41 +05301544 * Returns the referenced prefix for leafref under resolution.
1545 *
1546 * @return referenced prefix of leafref under resolution
1547 */
1548 private String refPrefixForLeafRef() {
1549
1550 String refPrefix;
1551 if (((YangLeafRef) getCurrentEntityToResolveFromStack()).getPathType() == YangPathArgType.ABSOLUTE_PATH) {
1552 List<YangAtomicPath> theList = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getAtomicPath();
1553 YangAtomicPath absPath = theList.iterator().next();
1554 refPrefix = absPath.getNodeIdentifier().getPrefix();
1555 } else {
1556 YangRelativePath relativePath = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getRelativePath();
1557 List<YangAtomicPath> theList = relativePath.getAtomicPathList();
1558 YangAtomicPath absPath = theList.iterator().next();
1559 refPrefix = absPath.getNodeIdentifier().getPrefix();
1560 }
1561 return refPrefix;
1562 }
1563
1564 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301565 * Performs inter file linking and resolution.
1566 *
1567 * @throws DataModelException a violation in data model rule
1568 */
1569 private void linkInterFileAndResolve()
1570 throws DataModelException {
1571
1572 while (getPartialResolvedStack().size() != 0) {
1573
1574 // Current node to resolve, it can be a YANG type or YANG uses.
1575 T entityToResolve = getCurrentEntityToResolveFromStack();
1576 // Check if linking is already done
1577 if (entityToResolve instanceof Resolvable) {
1578
1579 Resolvable resolvable = (Resolvable) entityToResolve;
1580 switch (resolvable.getResolvableStatus()) {
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301581 case RESOLVED: {
1582 /*
1583 * If the entity is already resolved in the stack, then pop
1584 * it and continue with the remaining stack elements to
1585 * resolve
1586 */
1587 getPartialResolvedStack().pop();
1588 break;
1589 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301590
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301591 case INTER_FILE_LINKED: {
1592 /*
1593 * If the top of the stack is already linked then resolve
1594 * the references and pop the entity and continue with
1595 * remaining stack elements to resolve
1596 */
1597 resolveTopOfStack(INTER_FILE);
1598 getPartialResolvedStack().pop();
1599 break;
1600 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301601
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301602 case INTRA_FILE_RESOLVED: {
1603 /*
1604 * If the top of the stack is intra file resolved then check
1605 * if top of stack is linked, if not link it using
1606 * import/include list and push the linked referred entity
1607 * to the stack, otherwise only push it to the stack.
1608 */
1609 linkInterFileTopOfStackRefUpdateStack();
1610 break;
1611 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301612
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301613 case UNDEFINED: {
1614 /*
1615 * In case of if-feature resolution, if referred "feature" is not
1616 * defined then the resolvable status will be undefined.
1617 */
1618 getPartialResolvedStack().pop();
1619 break;
1620 }
1621
1622 default: {
1623 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1624 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301625
1626 }
1627
1628 } else {
1629 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1630 }
1631
1632 }
1633
1634 }
1635
1636 /**
1637 * Links the top of the stack if it's inter-file and update stack.
1638 *
1639 * @throws DataModelException data model error
1640 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301641 private void linkInterFileTopOfStackRefUpdateStack()
1642 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301643
1644 /*
1645 * Obtain the referred node of top of stack entity under resolution
1646 */
1647 T referredNode = getRefNode();
1648
1649 /*
1650 * Check for null for scenario when it's not linked and inter-file
1651 * linking is required.
1652 */
1653 if (referredNode == null) {
1654
1655 /*
Bharat saraswal96dfef02016-06-16 00:29:12 +05301656 * Check if prefix is null or not, to identify whether to search in
1657 * import list or include list.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301658 */
Bharat saraswalcad0e652016-05-26 23:48:38 +05301659 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301660 if (resolveWithImport()) {
1661 return;
1662 }
1663 } else {
1664 if (resolveWithInclude()) {
1665 return;
1666 }
1667 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301668
1669 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1670 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1671 return;
1672 }
janani be18b5342016-07-13 21:06:41 +05301673 // If current entity is still not resolved, then
1674 // linking/resolution has failed.
1675 String errorInfo;
1676 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1677 errorInfo = TYPEDEF_LINKER_ERROR;
1678 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1679 errorInfo = GROUPING_LINKER_ERROR;
1680 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1681 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301682 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1683 errorInfo = BASE_LINKER_ERROR;
1684 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1685 errorInfo = IDENTITYREF_LINKER_ERROR;
janani be18b5342016-07-13 21:06:41 +05301686 } else {
1687 errorInfo = LEAFREF_LINKER_ERROR;
1688 }
1689 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301690 dataModelException.setLine(getLineNumber());
1691 dataModelException.setCharPosition(getCharPosition());
1692 throw dataModelException;
1693 } else {
1694 /*
1695 * If referred node is already linked, then just change the status
1696 * and push to the stack.
1697 */
janani be18b5342016-07-13 21:06:41 +05301698 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1699 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1700 if (referredNode instanceof YangLeaf) {
1701 YangLeaf yangleaf = (YangLeaf) referredNode;
1702 addUnResolvedLeafRefTypeToStack((T) yangleaf, (YangNode) yangleaf.getContainedIn());
1703 } else if (referredNode instanceof YangLeafList) {
1704 YangLeafList yangLeafList = (YangLeafList) referredNode;
1705 addUnResolvedLeafRefTypeToStack((T) yangLeafList, (YangNode) yangLeafList.getContainedIn());
1706 }
1707 } else {
1708 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1709 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1710 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301711 }
1712 }
1713
1714 /**
1715 * Finds and resolves with include list.
1716 *
1717 * @return true if resolved, false otherwise
1718 * @throws DataModelException a violation in data model rule
1719 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301720 private boolean resolveWithInclude()
1721 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301722 /*
1723 * Run through all the nodes in include list and search for referred
1724 * typedef/grouping at the root level.
1725 */
1726 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1727 YangNode linkedNode = null;
1728 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1729 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1730 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1731 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301732 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1733 linkedNode = findRefFeature(yangInclude.getIncludedNode());
janani be18b5342016-07-13 21:06:41 +05301734 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1735 boolean referredNode = findRefLeaf(yangInclude.getIncludedNode());
1736 /*
1737 * Update the current reference resolver to external
1738 * module/sub-module containing the referred typedef/grouping.
1739 */
1740 setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
1741
1742 return referredNode;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301743 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1744 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1745 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1746 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301747 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301748
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301749 if (linkedNode != null) {
1750 // Add the link to external entity.
1751 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
1752 /*
1753 * Update the current reference resolver to external
1754 * module/sub-module containing the referred typedef/grouping.
1755 */
1756 setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
1757 // Add the type/uses of referred typedef/grouping to the stack.
1758 addUnresolvedRecursiveReferenceToStack(linkedNode);
1759 return true;
1760 }
1761 }
1762 // If referred node can't be found return false.
1763 return false;
1764 }
1765
1766 /**
1767 * Finds and resolves with import list.
1768 *
1769 * @return true if resolved, false otherwise
1770 * @throws DataModelException a violation in data model rule
1771 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301772 private boolean resolveWithImport()
1773 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301774 /*
1775 * Run through import list to find the referred typedef/grouping.
1776 */
1777 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1778 /*
1779 * Match the prefix attached to entity under resolution with the
1780 * imported/included module/sub-module's prefix. If found, search
1781 * for the referred typedef/grouping at the root level.
1782 */
1783 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1784 YangNode linkedNode = null;
1785 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1786 linkedNode = findRefTypedef(yangImport.getImportedNode());
1787 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1788 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301789 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1790 linkedNode = findRefFeature(yangImport.getImportedNode());
janani be18b5342016-07-13 21:06:41 +05301791 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1792 boolean referredNode = findRefLeaf(yangImport.getImportedNode());
1793 /*
1794 * Update the current reference resolver to external
1795 * module/sub-module containing the referred
1796 * typedef/grouping.
1797 */
1798 setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
1799
1800 return referredNode;
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301801 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1802 linkedNode = findRefIdentity(yangImport.getImportedNode());
1803 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1804 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301805 }
1806 if (linkedNode != null) {
1807 // Add the link to external entity.
1808 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
1809 /*
1810 * Update the current reference resolver to external
Bharat saraswal96dfef02016-06-16 00:29:12 +05301811 * module/sub-module containing the referred
1812 * typedef/grouping.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301813 */
1814 setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
Bharat saraswal96dfef02016-06-16 00:29:12 +05301815 // Add the type/uses of referred typedef/grouping to the
1816 // stack.
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301817 addUnresolvedRecursiveReferenceToStack(linkedNode);
1818 return true;
1819 }
1820 /*
1821 * If referred node can't be found at root level break for loop,
1822 * and return false.
1823 */
1824 break;
1825 }
1826 }
1827 // If referred node can't be found return false.
1828 return false;
1829 }
1830
1831 /**
janani be18b5342016-07-13 21:06:41 +05301832 * Returns the status of referred leaf.
1833 *
1834 * @param importedNode the root node from a YANG file
1835 * @return status of the referred leaf
1836 * @throws DataModelException
1837 */
1838 private boolean findRefLeaf(YangNode importedNode) throws DataModelException {
1839
1840 boolean isReferredNodeFound = false;
1841 List<YangAtomicPath> absolutePathList = ((YangLeafRef) getCurrentEntityToResolveFromStack())
1842 .getAtomicPath();
1843 if (absolutePathList != null && !absolutePathList.isEmpty()) {
1844 Iterator<YangAtomicPath> listOfYangAtomicPath = absolutePathList.listIterator();
1845
1846 while (listOfYangAtomicPath.hasNext()) {
1847 YangAtomicPath absolutePath = listOfYangAtomicPath.next();
1848 String nodeName = absolutePath.getNodeIdentifier().getName();
1849
1850 if (importedNode.getChild() == null) {
1851 isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode, nodeName, (T) INTER_FILE_LINKED);
1852 break;
1853 }
1854 importedNode = importedNode.getChild();
1855
1856 YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(importedNode, nodeName);
1857 if (nodeFound == null) {
1858 isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode.getParent(), nodeName,
1859 (T) INTER_FILE_LINKED);
1860 } else {
1861 importedNode = nodeFound;
1862 }
1863 }
1864 }
1865 // TODO: Path predicates filling for inter file has to be done.
1866 return isReferredNodeFound;
1867 }
1868
1869 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301870 * Returns referred typedef/grouping node.
1871 *
1872 * @return referred typedef/grouping node
1873 * @throws DataModelException a violation in data model rule
1874 */
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +05301875 private T getRefNode()
1876 throws DataModelException {
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301877 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswal96dfef02016-06-16 00:29:12 +05301878 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1879 .getDataTypeExtendedInfo();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301880 return (T) derivedInfo.getReferredTypeDef();
1881 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1882 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301883 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1884 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani be18b5342016-07-13 21:06:41 +05301885 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1886 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301887 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1888 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1889 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1890 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301891 } else {
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301892 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
1893 "/uses/base/identityref");
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301894 }
1895 }
1896
1897 /**
1898 * Finds the referred grouping node at the root level of imported/included node.
1899 *
1900 * @param refNode module/sub-module node
1901 * @return referred grouping
1902 */
1903 private YangNode findRefGrouping(YangNode refNode) {
1904 YangNode tmpNode = refNode.getChild();
1905 while (tmpNode != null) {
1906 if (tmpNode instanceof YangGrouping) {
1907 if (tmpNode.getName()
1908 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1909 return tmpNode;
1910 }
1911 }
1912 tmpNode = tmpNode.getNextSibling();
1913 }
1914 return null;
1915 }
1916
1917 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +05301918 * Finds the referred feature node at the root level of imported/included node.
1919 *
1920 * @param refNode module/sub-module node
1921 * @return referred feature
1922 */
1923 private YangNode findRefFeature(YangNode refNode) {
1924 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1925 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1926
1927 if (featureList != null && !featureList.isEmpty()) {
1928 Iterator<YangFeature> iterator = featureList.iterator();
1929 while (iterator.hasNext()) {
1930 YangFeature feature = iterator.next();
1931 if (ifFeature.getName().equals(feature.getName())) {
1932 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1933 return refNode;
1934 }
1935 }
1936 }
1937 return null;
1938 }
1939
1940 /**
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05301941 * Finds the referred typedef node at the root level of imported/included node.
1942 *
1943 * @param refNode module/sub-module node
1944 * @return referred typedef
1945 */
1946 private YangNode findRefTypedef(YangNode refNode) {
1947 YangNode tmpNode = refNode.getChild();
1948 while (tmpNode != null) {
1949 if (tmpNode instanceof YangTypeDef) {
1950 if (tmpNode.getName()
1951 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1952 return tmpNode;
1953 }
1954 }
1955 tmpNode = tmpNode.getNextSibling();
1956 }
1957 return null;
1958 }
Shankara-Huaweidf7b9ca2016-07-14 11:35:34 +05301959
1960 /**
1961 * Finds the referred identity node at the root level of imported/included node.
1962 *
1963 * @param refNode module/sub-module node
1964 * @return referred identity
1965 */
1966 private YangNode findRefIdentity(YangNode refNode) {
1967 YangNode tmpNode = refNode.getChild();
1968 while (tmpNode != null) {
1969 if (tmpNode instanceof YangIdentity) {
1970 if (tmpNode.getName()
1971 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1972 return tmpNode;
1973 }
1974 }
1975 tmpNode = tmpNode.getNextSibling();
1976 }
1977 return null;
1978 }
1979
1980 /**
1981 * Finds the referred identity node at the root level of imported/included node.
1982 *
1983 * @param refNode module/sub-module node
1984 * @return referred identity
1985 */
1986 private YangNode findRefIdentityRef(YangNode refNode) {
1987 YangNode tmpNode = refNode.getChild();
1988 while (tmpNode != null) {
1989 if (tmpNode instanceof YangIdentity) {
1990 if (tmpNode.getName()
1991 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
1992 .getBaseIdentity().getName())) {
1993 return tmpNode;
1994 }
1995 }
1996 tmpNode = tmpNode.getNextSibling();
1997 }
1998 return null;
1999 }
Gaurav Agrawal0d43bb52016-05-17 18:06:38 +05302000}