blob: 0c21bc9e68baab5add766f1adda0bd16d0255289 [file] [log] [blame]
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yangutils.linker.impl;
18
Vidyashree Rama72719fa2016-07-15 14:06:56 +053019import java.io.Serializable;
20import java.util.Iterator;
21import java.util.LinkedList;
22import java.util.List;
23import java.util.Stack;
VinodKumarS-Huawei3b4cce02016-08-20 21:32:17 +053024
Bharat saraswalc2d3be12016-06-16 00:29:12 +053025import org.onosproject.yangutils.datamodel.Resolvable;
janani b0e4e8ae2016-07-13 21:06:41 +053026import org.onosproject.yangutils.datamodel.ResolvableType;
Vidyashree Rama72719fa2016-07-15 14:06:56 +053027import org.onosproject.yangutils.datamodel.TraversalType;
janani b0e4e8ae2016-07-13 21:06:41 +053028import org.onosproject.yangutils.datamodel.YangAtomicPath;
Bharat saraswald14cbe82016-07-14 13:26:18 +053029import org.onosproject.yangutils.datamodel.YangAugment;
30import org.onosproject.yangutils.datamodel.YangAugmentableNode;
Shankara-Huawei234cd092016-07-14 11:35:34 +053031import org.onosproject.yangutils.datamodel.YangBase;
Vidyashree Ramab3670472016-08-06 15:49:56 +053032import org.onosproject.yangutils.datamodel.YangCompilerAnnotation;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053033import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053034import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
janani bebb143d2016-07-14 19:35:22 +053035import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053036import org.onosproject.yangutils.datamodel.YangFeature;
37import org.onosproject.yangutils.datamodel.YangFeatureHolder;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053038import org.onosproject.yangutils.datamodel.YangGrouping;
Shankara-Huawei234cd092016-07-14 11:35:34 +053039import org.onosproject.yangutils.datamodel.YangIdentity;
40import org.onosproject.yangutils.datamodel.YangIdentityRef;
Bharat saraswalaf413b82016-07-14 15:18:20 +053041import org.onosproject.yangutils.datamodel.YangIfFeature;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053042import org.onosproject.yangutils.datamodel.YangImport;
43import org.onosproject.yangutils.datamodel.YangInclude;
janani b0e4e8ae2016-07-13 21:06:41 +053044import org.onosproject.yangutils.datamodel.YangInput;
45import org.onosproject.yangutils.datamodel.YangLeaf;
46import org.onosproject.yangutils.datamodel.YangLeafList;
47import org.onosproject.yangutils.datamodel.YangLeafRef;
Vidyashree Ramab3670472016-08-06 15:49:56 +053048import org.onosproject.yangutils.datamodel.YangList;
janani b0e4e8ae2016-07-13 21:06:41 +053049import org.onosproject.yangutils.datamodel.YangModule;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053050import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053051import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
janani b0e4e8ae2016-07-13 21:06:41 +053052import org.onosproject.yangutils.datamodel.YangOutput;
53import org.onosproject.yangutils.datamodel.YangPathArgType;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053054import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani b0e4e8ae2016-07-13 21:06:41 +053055import org.onosproject.yangutils.datamodel.YangRelativePath;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053056import org.onosproject.yangutils.datamodel.YangResolutionInfo;
janani b0e4e8ae2016-07-13 21:06:41 +053057import org.onosproject.yangutils.datamodel.YangRpc;
58import org.onosproject.yangutils.datamodel.YangSubModule;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053059import org.onosproject.yangutils.datamodel.YangType;
60import org.onosproject.yangutils.datamodel.YangTypeDef;
61import org.onosproject.yangutils.datamodel.YangUses;
Bharat saraswald14cbe82016-07-14 13:26:18 +053062import org.onosproject.yangutils.datamodel.YangXPathResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053063import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053064import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
janani bebb143d2016-07-14 19:35:22 +053065import org.onosproject.yangutils.datamodel.utils.YangConstructType;
janani b0e4e8ae2016-07-13 21:06:41 +053066import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +053067import org.onosproject.yangutils.linker.YangLinkingPhase;
Bharat saraswald14cbe82016-07-14 13:26:18 +053068import org.onosproject.yangutils.linker.exceptions.LinkerException;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053069
Vidyashree Rama72719fa2016-07-15 14:06:56 +053070import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
71import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
72import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
73import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
janani bebb143d2016-07-14 19:35:22 +053074import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053075import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
76import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
77import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
78import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053079import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNDEFINED;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053080import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +053081import static org.onosproject.yangutils.linker.YangLinkingPhase.INTER_FILE;
82import static org.onosproject.yangutils.linker.YangLinkingPhase.INTRA_FILE;
Bharat saraswald14cbe82016-07-14 13:26:18 +053083import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
janani bebb143d2016-07-14 19:35:22 +053084import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
85import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getValidNodeIdentifier;
86import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.skipInvalidDataNodes;
Bharat saraswalaf413b82016-07-14 15:18:20 +053087import static org.onosproject.yangutils.utils.UtilConstants.BASE_LINKER_ERROR;
janani bebb143d2016-07-14 19:35:22 +053088import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053089import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
Vidyashree Rama5daea742016-05-20 16:29:25 +053090import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
Bharat saraswalaf413b82016-07-14 15:18:20 +053091import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
92import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +053093import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
94import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
95import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
96import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
janani bebb143d2016-07-14 19:35:22 +053097import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053098import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053099
100/**
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530101 * Represents implementation of resolution object which will be resolved by
102 * linker.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530103 *
104 * @param <T> type of resolution entity uses / type
105 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530106public class YangResolutionInfoImpl<T>
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530107 implements YangResolutionInfo<T>, Serializable {
108
109 private static final long serialVersionUID = 806201658L;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530110
111 /**
112 * Information about the entity that needs to be resolved.
113 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530114 private YangEntityToResolveInfoImpl<T> entityToResolveInfo;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530115
116 /**
117 * Error line number.
118 */
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530119 private transient int lineNumber;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530120
121 /**
122 * Error character position in number.
123 */
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530124 private transient int charPosition;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530125
126 /**
127 * Current module/sub-module reference, will be used in inter-file/
128 * inter-jar scenario to get the import/include list.
129 */
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530130 private YangReferenceResolver curReferenceResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530131
132 /**
133 * Stack for type/uses is maintained for hierarchical references, this is
134 * used during resolution.
135 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530136 private Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530137
138 /**
139 * It is private to ensure the overloaded method be invoked to create an
140 * object.
141 */
142 @SuppressWarnings("unused")
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530143 private YangResolutionInfoImpl() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530144 }
145
146 /**
147 * Creates a resolution information object with all the inputs.
148 *
149 * @param dataNode current parsable data node
150 * @param holderNode parent YANG node
151 * @param lineNumber error line number
152 * @param charPositionInLine error character position in line
153 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530154 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
155 setEntityToResolveInfo(new YangEntityToResolveInfoImpl<>());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530156 getEntityToResolveInfo().setEntityToResolve(dataNode);
157 getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
158 this.setLineNumber(lineNumber);
159 this.setCharPosition(charPositionInLine);
160 setPartialResolvedStack(new Stack<>());
161 }
162
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530163 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530164 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
165 throws DataModelException {
166
167 setCurReferenceResolver(dataModelRootNode);
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530168 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530169 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
170 * YANG leafref or YANG base or YANG identityref.
171 */
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530172 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
173
174 // Check if linking is already done
175 if (entityToResolve instanceof Resolvable) {
176 Resolvable resolvable = (Resolvable) entityToResolve;
177 if (resolvable.getResolvableStatus() == RESOLVED) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530178 /*
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530179 * entity is already resolved, so nothing to do
180 */
181 return;
182 }
183 } else {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530184 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
Shankara-Huawei234cd092016-07-14 11:35:34 +0530185 "type/uses/if-feature/leafref/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530186 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530187 // Push the initial entity to resolve in stack.
188 addInPartialResolvedStack(getEntityToResolveInfo());
189
190 linkAndResolvePartialResolvedStack();
janani b0e4e8ae2016-07-13 21:06:41 +0530191
192 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530193 }
194
195 /**
196 * Resolves linking with ancestors.
197 *
198 * @throws DataModelException a violation of data model rules
199 */
200 private void linkAndResolvePartialResolvedStack()
201 throws DataModelException {
202
203 while (getPartialResolvedStack().size() != 0) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530204 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530205 * Current node to resolve, it can be a YANG type or YANG uses or
206 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
207 */
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530208 T entityToResolve = getCurrentEntityToResolveFromStack();
209 // Check if linking is already done
210 if (entityToResolve instanceof Resolvable) {
211
212 Resolvable resolvable = (Resolvable) entityToResolve;
213 switch (resolvable.getResolvableStatus()) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530214 case RESOLVED: {
215 /*
216 * If the entity is already resolved in the stack, then pop
217 * it and continue with the remaining stack elements to
218 * resolve
219 */
220 getPartialResolvedStack().pop();
221 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530222 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530223
224 case LINKED: {
225 /*
226 * If the top of the stack is already linked then resolve
227 * the references and pop the entity and continue with
228 * remaining stack elements to resolve.
229 */
230 resolveTopOfStack(INTRA_FILE);
231 getPartialResolvedStack().pop();
232 break;
233 }
234
235 case INTRA_FILE_RESOLVED: {
236 /*
237 * Pop the top of the stack.
238 */
239 getPartialResolvedStack().pop();
240 break;
241 }
242
243 case UNRESOLVED: {
244 linkTopOfStackReferenceUpdateStack();
245
246 if (resolvable.getResolvableStatus() == UNRESOLVED) {
247 // If current entity is still not resolved, then
248 // linking/resolution has failed.
249 String errorInfo;
250 if (resolvable instanceof YangType) {
251 errorInfo = TYPEDEF_LINKER_ERROR;
252 } else if (resolvable instanceof YangUses) {
253 errorInfo = GROUPING_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +0530254 } else if (resolvable instanceof YangIfFeature) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530255 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530256 } else if (resolvable instanceof YangBase) {
257 errorInfo = BASE_LINKER_ERROR;
258 } else if (resolvable instanceof YangIdentityRef) {
259 errorInfo = IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +0530260 } else {
261 errorInfo = LEAFREF_LINKER_ERROR;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530262 }
263 DataModelException dataModelException =
264 new DataModelException(errorInfo);
265 dataModelException.setLine(getLineNumber());
266 dataModelException.setCharPosition(getCharPosition());
267 throw dataModelException;
268 }
269 break;
270 }
271 default: {
272 throw new DataModelException("Data Model Exception: Unsupported, linker state");
273 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530274
275 }
276
277 } else {
janani b0e4e8ae2016-07-13 21:06:41 +0530278 throw new DataModelException(
Shankara-Huawei234cd092016-07-14 11:35:34 +0530279 "Data Model Exception: Entity to resolved is other than type/uses/if-feature" +
280 "/leafref/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530281 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530282 }
283
284 }
285
286 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530287 * Adds the leafref/identityref type to the type, which has derived type referring to
288 * typedef with leafref/identityref type.
janani b0e4e8ae2016-07-13 21:06:41 +0530289 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530290 private void addDerivedRefTypeToRefTypeResolutionList()
291 throws DataModelException {
janani b0e4e8ae2016-07-13 21:06:41 +0530292
293 YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
294
295 // If holder is typedef return.
296 if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
297 return;
298 }
299
300 // If entity is not type return.
301 if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
302 return;
303 }
304
305 YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
306
307 // If type is not resolved return.
308 if (yangType.getResolvableStatus() != RESOLVED) {
309 return;
310 }
311
312 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
313
Vidyashree Ramab3670472016-08-06 15:49:56 +0530314 // If the derived types referred type is not leafref/identityref return
Shankara-Huawei234cd092016-07-14 11:35:34 +0530315 if ((derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) &&
316 (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.IDENTITYREF)) {
janani b0e4e8ae2016-07-13 21:06:41 +0530317 return;
318 }
319
320 T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
321
322 while (extendedInfo instanceof YangDerivedInfo) {
323 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
324 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
325 .getDataTypeExtendedInfo();
326 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530327
janani b0e4e8ae2016-07-13 21:06:41 +0530328 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530329 * Backup the derived types leafref/identityref info, delete all the info in current type,
330 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
331 * create a leafref/identityref resolution info using the current resolution info and
332 * add to leafref/identityref resolution list.
janani b0e4e8ae2016-07-13 21:06:41 +0530333 */
Shankara-Huawei234cd092016-07-14 11:35:34 +0530334 if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
335 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
336 yangType.resetYangType();
janani b0e4e8ae2016-07-13 21:06:41 +0530337
Shankara-Huawei234cd092016-07-14 11:35:34 +0530338 yangType.setResolvableStatus(RESOLVED);
339 yangType.setDataType(YangDataTypes.LEAFREF);
340 yangType.setDataTypeName(LEAFREF);
341 yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
342 leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
janani bebb143d2016-07-14 19:35:22 +0530343 leafRefInTypeDef.setParentNodeOfLeafref(potentialAncestorWithReferredNode);
janani b0e4e8ae2016-07-13 21:06:41 +0530344
Shankara-Huawei234cd092016-07-14 11:35:34 +0530345 // Add resolution information to the list.
346 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
janani bebb143d2016-07-14 19:35:22 +0530347 potentialAncestorWithReferredNode,
348 getLineNumber(), getCharPosition());
Shankara-Huawei234cd092016-07-14 11:35:34 +0530349 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani bebb143d2016-07-14 19:35:22 +0530350 ResolvableType.YANG_LEAFREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530351 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
352
353 } else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
354
355 YangIdentityRef identityRefInTypeDef = (YangIdentityRef) extendedInfo;
356 yangType.resetYangType();
357
358 yangType.setResolvableStatus(RESOLVED);
359 yangType.setDataType(YangDataTypes.IDENTITYREF);
360 yangType.setDataTypeName(IDENTITYREF);
361 yangType.setDataTypeExtendedInfo(identityRefInTypeDef);
362 identityRefInTypeDef.setResolvableStatus(UNRESOLVED);
363
364 // Add resolution information to the list.
365 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
janani bebb143d2016-07-14 19:35:22 +0530366 potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
Shankara-Huawei234cd092016-07-14 11:35:34 +0530367 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani bebb143d2016-07-14 19:35:22 +0530368 ResolvableType.YANG_IDENTITYREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530369 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
370 }
janani b0e4e8ae2016-07-13 21:06:41 +0530371 }
372
373 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530374 * Resolves the current entity in the stack.
375 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530376 private void resolveTopOfStack(YangLinkingPhase linkingPhase)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530377 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530378 List<T> entityToResolve = (List<T>) ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
379 if (entityToResolve != null && !entityToResolve.isEmpty()) {
380 Iterator<T> entityToResolveIterator = entityToResolve.listIterator();
381 while (entityToResolveIterator.hasNext()) {
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530382 addUnresolvedEntitiesToResolutionList(entityToResolveIterator.next());
janani bebb143d2016-07-14 19:35:22 +0530383 }
384 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530385 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
386 && ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
janani b0e4e8ae2016-07-13 21:06:41 +0530387 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530388 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
389 }
390 }
391
392 /**
janani bebb143d2016-07-14 19:35:22 +0530393 * Adds the unresolved entities to the resolution list.
394 *
395 * @param entityToResolve entity to resolve
396 * @throws DataModelException a violation of data model rules
397 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530398 private void addUnresolvedEntitiesToResolutionList(T entityToResolve)
399 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530400 if (entityToResolve instanceof YangEntityToResolveInfoImpl) {
401 YangEntityToResolveInfoImpl entityToResolveInfo = (YangEntityToResolveInfoImpl) entityToResolve;
402 if (entityToResolveInfo.getEntityToResolve() instanceof YangLeafRef) {
403 YangLeafRef leafref = (YangLeafRef) entityToResolveInfo.getEntityToResolve();
404 YangNode parentNodeOfLeafref = entityToResolveInfo.getHolderOfEntityToResolve();
405 leafref.setParentNodeOfLeafref(parentNodeOfLeafref);
406 if (leafref.getResolvableStatus() == UNRESOLVED) {
407 leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
408 }
janani bebb143d2016-07-14 19:35:22 +0530409 }
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530410
411 // Add resolution information to the list.
412 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(
413 entityToResolveInfo.getEntityToResolve(), entityToResolveInfo.getHolderOfEntityToResolve(),
414 entityToResolveInfo.getLineNumber(), entityToResolveInfo.getCharPosition());
415 addResolutionInfo(resolutionInfoImpl);
janani bebb143d2016-07-14 19:35:22 +0530416 }
417 }
418
419 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530420 * Resolves linking for a node child and siblings.
421 *
422 * @throws DataModelException data model error
423 */
424 private void linkTopOfStackReferenceUpdateStack()
425 throws DataModelException {
426
janani bebb143d2016-07-14 19:35:22 +0530427 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
428 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
429 return;
430 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530431 /*
432 * Check if self file reference is there, this will not check for the
433 * scenario when prefix is not present and type/uses is present in
434 * sub-module from include list.
435 */
436 if (!isCandidateForSelfFileReference()) {
437 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
438 return;
439 }
440
441 /**
442 * Try to resolve the top of the stack and update partial resolved stack
443 * if there is recursive references
444 */
445 YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
446 .getHolderOfEntityToResolve();
447
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530448 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
449 resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
450 return;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530451 } else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
452 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
453 resolveSelfFileLinkingForBaseAndIdentityref();
454 return;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530455 } else {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530456
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530457 YangType type = null;
458 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
459 type = (YangType) getCurrentEntityToResolveFromStack();
460 }
461
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530462 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530463 * Traverse up in the ancestor tree to check if the referred node is
464 * defined
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530465 */
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530466 while (potentialAncestorWithReferredNode != null) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530467
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530468 /**
469 * Check for the referred node defined in a ancestor scope
470 */
471 YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
472 if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
473 return;
474 }
475
476 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530477
478 if (type != null && potentialAncestorWithReferredNode != null) {
479 if (potentialAncestorWithReferredNode.getParent() == null) {
480 type.setTypeNotResolvedTillRootNode(true);
481 }
482 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530483 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530484 }
485
486 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530487 * In case prefix is not present or it's self prefix it's a candidate for inter-file
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530488 * resolution via include list.
489 */
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530490 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530491 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
492 }
493 }
494
495 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530496 * Resolves self file linking for base/identityref.
497 *
498 * @throws DataModelException a violation of data model rules
499 */
500 private void resolveSelfFileLinkingForBaseAndIdentityref()
501 throws DataModelException {
502
503 boolean referredIdentityFound = false;
504 String nodeName = null;
505
506 if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
janani bebb143d2016-07-14 19:35:22 +0530507 nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530508 }
509
510 if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
511 nodeName = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName();
512 }
513
514 if (getCurReferenceResolver() instanceof YangModule) {
515 YangModule rootNode = (YangModule) getCurReferenceResolver();
516 // Sends list of nodes for finding the target identity.
517 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
518 } else if (getCurReferenceResolver() instanceof YangSubModule) {
519 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
520 // Sends list of nodes for finding the target identity.
521 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
522 }
523
524 if (referredIdentityFound) {
525 return;
526 }
527
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530528 /*
529 * In case prefix is not present or it's self prefix it's a candidate for inter-file
530 * resolution via include list.
531 */
532 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530533 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
534 }
535 }
536
537 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530538 * Returns the root parent with respect to the ancestor count from leafref.
539 *
540 * @param ancestorCount count of node where parent node can be reached
541 * @param currentParent current parent node
542 * @return root node
543 * @throws DataModelException a violation of data model rules
544 */
545 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
546 throws DataModelException {
547
548 int currentParentCount = 1;
549 while (currentParentCount < ancestorCount) {
550 if (currentParent.getParent() == null) {
551 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
552 }
553 currentParent = currentParent.getParent();
554 currentParentCount = currentParentCount + 1;
555 }
556 return currentParent;
557 }
558
559 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530560 * Resolves self file linking for if-feature.
561 *
562 * @param potentialAncestorWithReferredNode if-feature holder node
563 * @throws DataModelException DataModelException a violation of data model
564 * rules
565 */
566 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
567 throws DataModelException {
568
569 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
570 YangNode potentialReferredNode = (YangNode) featureHolder;
571 if (isReferredNode(potentialReferredNode)) {
572
573 // Adds reference link of entity to the node under resolution.
574 addReferredEntityLink(potentialReferredNode, LINKED);
575
576 /**
577 * resolve the reference and update the partial resolution stack
578 * with any further recursive references
579 */
580 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
581 return;
582 }
583
584 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530585 * In case prefix is not present or it's self prefix it's a candidate for inter-file
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530586 * resolution via include list.
587 */
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530588 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530589 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
590 }
591 }
592
janani b0e4e8ae2016-07-13 21:06:41 +0530593 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530594 * Returns the status of the referred identity found for base/identityref.
595 *
janani bebb143d2016-07-14 19:35:22 +0530596 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
Shankara-Huawei234cd092016-07-14 11:35:34 +0530597 * @param ancestorWithTheReferredNode the parent node of base/identityref
598 * @return status of referred base/identityref
599 * @throws DataModelException a violation of data model rules
600 */
601 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
602 throws DataModelException {
603
604 // When child is not present return.
605 if (ancestorWithTheReferredNode.getChild() == null) {
606 return false;
607 }
608
609 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
610
611 // Checks all the siblings under the node and returns the matched node.
612 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
613
614 if (nodeFound != null) {
615 // Adds reference link of entity to the node under resolution.
616 addReferredEntityLink(nodeFound, LINKED);
617
618 /**
619 * resolve the reference and update the partial resolution stack with any further recursive references
620 */
621 addUnresolvedRecursiveReferenceToStack(nodeFound);
622 return true;
623 }
624
625 return false;
626 }
627
628 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530629 * Adds the unresolved constructs to stack which has to be resolved for leafref.
630 *
janani bebb143d2016-07-14 19:35:22 +0530631 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
janani b0e4e8ae2016-07-13 21:06:41 +0530632 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
633 */
634 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
635
636 YangType referredTypeInLeafOrLeafList;
637 if (yangleafOrLeafList instanceof YangLeaf) {
638 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
639 referredTypeInLeafOrLeafList = leaf.getDataType();
640 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
641 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
642 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
643 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
644 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
645 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
646 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
647 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
648 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
649 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
650 }
651 } else {
652 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
653 referredTypeInLeafOrLeafList = leafList.getDataType();
654 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
655 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
656 unResolvedEntityInfo
657 .setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
658 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
659 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
660 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
661 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
662 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
663 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
664 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
665 }
666 }
667 }
668
669 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530670 * Returns feature holder(module/sub-module node) .
671 *
672 * @param potentialAncestorWithReferredNode if-feature holder node
673 */
674 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
675 while (potentialAncestorWithReferredNode != null) {
676 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
677 return (YangFeatureHolder) potentialAncestorWithReferredNode;
678 }
679 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
680 }
681 return null;
682 }
683
684 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530685 * Checks if the reference in self file or in external file.
686 *
687 * @return true if self file reference, false otherwise
688 * @throws DataModelException a violation of data model rules
689 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530690 private boolean isCandidateForSelfFileReference()
691 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530692 String prefix = getRefPrefix();
693 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
694 }
695
696 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530697 * Checks for the referred parent node for the leafref path.
698 *
699 * @param potentialReferredNode potential referred node
700 * @return the reffered parent node of leaf/leaf-list
701 * @throws DataModelException data model errors
702 */
703 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
704 throws DataModelException {
705
706 while (potentialReferredNode != null) {
707 if (potentialReferredNode instanceof YangInput) {
708 if (referredNodeName.equalsIgnoreCase(INPUT)) {
709 return potentialReferredNode;
710 }
711 } else if (potentialReferredNode instanceof YangOutput) {
712 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
713 return potentialReferredNode;
714 }
715 }
716 // Check if the potential referred node is the actual referred node
717 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
718 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
719 if (potentialReferredNode.getParent() instanceof YangRpc) {
720 potentialReferredNode = potentialReferredNode.getNextSibling();
721 } else {
722 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
723 }
724 }
725 return potentialReferredNode;
726 }
727 potentialReferredNode = potentialReferredNode.getNextSibling();
728 }
729 return null;
730 }
731
732 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530733 * Checks for the referred parent node for the base/identity.
734 *
735 * @param potentialReferredNode potential referred node
736 * @return the reffered parent node of base/identity.
737 * @throws DataModelException data model errors
738 */
739 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530740 String referredNodeName)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530741 throws DataModelException {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530742
743 while (potentialReferredNode != null) {
744 if (potentialReferredNode instanceof YangIdentity) {
745 // Check if the potential referred node is the actual referred node
746 if (isReferredNodeForIdentity(potentialReferredNode, referredNodeName)) {
747 return potentialReferredNode;
748 }
749 }
750 potentialReferredNode = potentialReferredNode.getNextSibling();
751 }
752 return null;
753 }
754
755 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530756 * Checks if the current reference node name and the name in the path are equal.
757 *
758 * @param currentReferredNode the node where the reference is pointed
janani bebb143d2016-07-14 19:35:22 +0530759 * @param nameOfNodeinPath name of the node in the path
janani b0e4e8ae2016-07-13 21:06:41 +0530760 * @return status of the match between the name
761 * @throws DataModelException a violation of data model rules
762 */
763 private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
764 throws DataModelException {
765
766 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
767 /*
768 * Check if name of node name matches with the current reference
769 * node.
770 */
771 return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
772 } else {
773 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
774 }
775 }
776
777 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530778 * Checks if the current reference node name and the name in the base/identityref base are equal.
779 *
janani bebb143d2016-07-14 19:35:22 +0530780 * @param currentReferredNode the node where the reference is pointed
Shankara-Huawei234cd092016-07-14 11:35:34 +0530781 * @param nameOfIdentityRefBase name of the base in the base/identityref base
782 * @return status of the match between the name
783 * @throws DataModelException a violation of data model rules
784 */
785 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
786 throws DataModelException {
787
788 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
789 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530790
791 //Check if name of node name matches with the current reference node.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530792 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
793 } else {
794 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref");
795 }
796 }
797
798 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530799 * Checks for the referred node defined in a ancestor scope.
800 *
801 * @param potentialReferredNode potential referred node
802 * @return status of resolution and updating the partial resolved stack with
803 * the any recursive references
janani b0e4e8ae2016-07-13 21:06:41 +0530804 * @throws DataModelException a violation of data model rules
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530805 */
806 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
807 throws DataModelException {
808 while (potentialReferredNode != null) {
809
810 // Check if the potential referred node is the actual referred node
811 if (isReferredNode(potentialReferredNode)) {
812
813 // Adds reference link of entity to the node under resolution.
814 addReferredEntityLink(potentialReferredNode, LINKED);
815
816 /**
817 * resolve the reference and update the partial resolution stack
818 * with any further recursive references
819 */
820 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
821
822 /*
823 * return true, since the reference is linked and any recursive
824 * unresolved references is added to the stack
825 */
826 return true;
827 }
828
829 potentialReferredNode = potentialReferredNode.getNextSibling();
830 }
831 return false;
832 }
833
834 /**
835 * Checks if the potential referred node is the actual referred node.
836 *
837 * @param potentialReferredNode typedef/grouping node
838 * @return true if node is of resolve type otherwise false
839 * @throws DataModelException a violation of data model rules
840 */
841 private boolean isReferredNode(YangNode potentialReferredNode)
842 throws DataModelException {
843 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
844 if (potentialReferredNode instanceof YangTypeDef) {
845 /*
846 * Check if name of node name matches with the entity being
847 * resolved
848 */
849 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
850 }
851 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
852 if (potentialReferredNode instanceof YangGrouping) {
853 /*
854 * Check if name of node name matches with the entity being
855 * resolved
856 */
857 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
858 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530859 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
860 if (potentialReferredNode instanceof YangFeatureHolder) {
861 /*
862 * Check if name of node name matches with the entity being
863 * resolved
864 */
865 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
866 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530867 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
868 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
869 if (potentialReferredNode instanceof YangIdentity) {
870 /*
871 * Check if name of node name matches with the entity being
872 * resolved
873 */
874 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
875 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530876 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530877 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
janani bebb143d2016-07-14 19:35:22 +0530878 "uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530879 }
880 return false;
881 }
882
883 /**
884 * Checks if node name is same as name in resolution info, i.e. name of
885 * typedef/grouping is same as name of type/uses.
886 *
887 * @param node typedef/grouping node
888 * @return true if node name is same as name in resolution info, otherwise
889 * false
890 * @throws DataModelException a violation of data model rules
891 */
892
893 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
894 throws DataModelException {
895 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
896 if (node.getName().contentEquals(
897 ((YangType<?>) getCurrentEntityToResolveFromStack())
898 .getDataTypeName())) {
899 return true;
900 }
901 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
902 if (node.getName().contentEquals(
903 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
904 return true;
905 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530906 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
907 return isFeatureDefinedInNode(node);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530908 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
909 if (node.getName().contentEquals(
910 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
911 return true;
912 }
913 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
914 if (node.getName().contentEquals(
915 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
916 return true;
917 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530918 } else {
919 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
920 }
921 return false;
922 }
923
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530924 private boolean isFeatureDefinedInNode(YangNode node)
925 throws DataModelException {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530926 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
927 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
928 if (featureList != null && !featureList.isEmpty()) {
929 Iterator<YangFeature> iterator = featureList.iterator();
930 while (iterator.hasNext()) {
931 YangFeature feature = iterator.next();
932 if (ifFeature.getName().equals(feature.getName())) {
933 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
934 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
935 return true;
936 }
937 }
938 }
939 return false;
940 }
941
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530942 /**
943 * Adds reference of grouping/typedef in uses/type.
944 *
945 * @param referredNode grouping/typedef node being referred
946 * @param linkedStatus linked status if success.
947 * @throws DataModelException a violation of data model rules
948 */
949 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
950 throws DataModelException {
951 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530952 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
953 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530954 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
955 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
956 ((YangUses) getCurrentEntityToResolveFromStack())
957 .setRefGroup((YangGrouping) referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530958 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
959 // do nothing , referred node is already set
janani b0e4e8ae2016-07-13 21:06:41 +0530960 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
961 // do nothing , referred node is already set
Shankara-Huawei234cd092016-07-14 11:35:34 +0530962 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
963 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
964 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
965 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530966 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530967 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +0530968 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530969 }
970
971 // Sets the resolution status in inside the type/uses.
972 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
973 }
974
975 /**
976 * Checks if type/grouping has further reference to typedef/ unresolved
977 * uses. Add it to the partial resolve stack and return the status of
978 * addition to stack.
979 *
980 * @param referredNode grouping/typedef node
981 * @throws DataModelException a violation of data model rules
982 */
983 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
984 throws DataModelException {
985 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530986
987 //Checks if typedef type is derived
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530988 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530989
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530990 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530991 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
992 .getTypeDefBaseType());
993 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530994 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530995 }
996
997 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
998 /*
999 * Search if the grouping has any un resolved uses child, if so
1000 * return true, else return false.
1001 */
1002 addUnResolvedUsesToStack(referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301003 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1004 addUnResolvedIfFeatureToStack(referredNode);
janani b0e4e8ae2016-07-13 21:06:41 +05301005 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1006 // do nothing , referred node is already set
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301007 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
Shankara-Huawei234cd092016-07-14 11:35:34 +05301008 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1009 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301010
1011 //Search if the identity has any un resolved base, if so return true, else return false.
Shankara-Huawei234cd092016-07-14 11:35:34 +05301012 addUnResolvedBaseToStack(referredNode);
1013 } else {
1014 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
janani bebb143d2016-07-14 19:35:22 +05301015 "base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301016 }
1017 }
1018
1019 /**
1020 * Returns if there is any unresolved uses in grouping.
1021 *
1022 * @param node grouping/typedef node
1023 */
1024 private void addUnResolvedUsesToStack(YangNode node) {
1025
Vidyashree Ramab3670472016-08-06 15:49:56 +05301026 //Search the grouping node's children for presence of uses node.
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301027 TraversalType curTraversal = ROOT;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301028 YangNode curNode = node.getChild();
1029 while (curNode != null) {
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301030 if (curNode.getName().equals(node.getName())) {
1031 // if we have traversed all the child nodes, then exit from loop
1032 return;
1033 }
1034
1035 // if child nodes has uses, then add it to resolution stack
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301036 if (curNode instanceof YangUses) {
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301037 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301038 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1039 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301040 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301041 }
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301042
1043 // Traversing all the child nodes of grouping
1044 if (curTraversal != PARENT && curNode.getChild() != null) {
1045 curTraversal = CHILD;
1046 curNode = curNode.getChild();
1047 } else if (curNode.getNextSibling() != null) {
1048 curTraversal = SIBILING;
1049 curNode = curNode.getNextSibling();
1050 } else {
1051 curTraversal = PARENT;
1052 curNode = curNode.getParent();
1053 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301054 }
1055 }
1056
1057 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301058 * Returns if there is any unresolved if-feature in feature.
1059 *
1060 * @param node module/submodule node
1061 */
1062 private void addUnResolvedIfFeatureToStack(YangNode node) {
1063 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1064 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1065 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1066 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1067 while (ifFeatureIterator.hasNext()) {
1068 YangIfFeature ifFeature = ifFeatureIterator.next();
1069 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1070 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1071 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1072 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1073 }
1074 }
1075 }
1076
1077 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +05301078 * Returns if there is any unresolved base in identity.
1079 *
1080 * @param node module/submodule node
1081 */
1082 private void addUnResolvedBaseToStack(YangNode node) {
1083
1084 YangIdentity curNode = (YangIdentity) node;
1085 if (curNode.getBaseNode() != null) {
1086 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1087 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1088 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1089 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1090 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1091
1092 }
1093 }
1094 }
1095
1096
1097 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301098 * Returns stack of YANG type with partially resolved YANG construct
1099 * hierarchy.
1100 *
1101 * @return partial resolved YANG construct stack
1102 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301103 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301104 return partialResolvedStack;
1105 }
1106
1107 /**
1108 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1109 *
1110 * @param partialResolvedStack partial resolved YANG construct stack
1111 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301112 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301113 this.partialResolvedStack = partialResolvedStack;
1114 }
1115
1116 /**
1117 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1118 *
1119 * @param partialResolvedInfo partial resolved YANG construct stack
1120 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301121 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301122 getPartialResolvedStack().push(partialResolvedInfo);
1123 }
1124
1125 /**
1126 * Retrieves the next entity in the stack that needs to be resolved. It is
1127 * assumed that the caller ensures that the stack is not empty.
1128 *
1129 * @return next entity in the stack that needs to be resolved
1130 */
1131 private T getCurrentEntityToResolveFromStack() {
1132 return getPartialResolvedStack().peek().getEntityToResolve();
1133 }
1134
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301135 @Override
1136 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301137 return entityToResolveInfo;
1138 }
1139
1140 /**
1141 * Sets information about the entity that needs to be resolved.
1142 *
1143 * @param entityToResolveInfo information about the entity that needs to be
1144 * resolved
1145 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301146 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301147 this.entityToResolveInfo = entityToResolveInfo;
1148 }
1149
1150 @Override
1151 public int getLineNumber() {
1152 return lineNumber;
1153 }
1154
1155 @Override
1156 public int getCharPosition() {
1157 return charPosition;
1158 }
1159
1160 @Override
1161 public void setLineNumber(int lineNumber) {
1162 this.lineNumber = lineNumber;
1163 }
1164
1165 @Override
1166 public void setCharPosition(int charPositionInLine) {
1167 this.charPosition = charPositionInLine;
1168 }
1169
1170 /**
1171 * Returns current module/sub-module reference, will be used in inter-file/
1172 * inter-jar scenario to get the import/include list.
1173 *
1174 * @return current module/sub-module reference
1175 */
1176 private YangReferenceResolver getCurReferenceResolver() {
1177 return curReferenceResolver;
1178 }
1179
1180 /**
1181 * Sets current module/sub-module reference, will be used in inter-file/
1182 * inter-jar scenario to get the import/include list.
1183 *
1184 * @param curReferenceResolver current module/sub-module reference
1185 */
1186 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1187 this.curReferenceResolver = curReferenceResolver;
1188 }
1189
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301190 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301191 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1192 throws DataModelException {
1193
1194 setCurReferenceResolver(dataModelRootNode);
1195
1196 // Current node to resolve, it can be a YANG type or YANG uses.
1197 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1198
1199 // Check if linking is already done
1200 if (entityToResolve instanceof Resolvable) {
1201 Resolvable resolvable = (Resolvable) entityToResolve;
1202 if (resolvable.getResolvableStatus() == RESOLVED) {
1203 return;
1204 }
1205 } else {
1206 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1207 }
1208
janani bebb143d2016-07-14 19:35:22 +05301209 if (entityToResolve instanceof YangXPathResolver && !(entityToResolve instanceof YangLeafRef)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +05301210 //Process x-path linking.
janani bebb143d2016-07-14 19:35:22 +05301211 processXPathLinking(entityToResolve, dataModelRootNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301212
Bharat saraswald14cbe82016-07-14 13:26:18 +05301213 } else {
janani b0e4e8ae2016-07-13 21:06:41 +05301214
Bharat saraswald14cbe82016-07-14 13:26:18 +05301215 // Push the initial entity to resolve in stack.
1216 addInPartialResolvedStack(getEntityToResolveInfo());
1217
1218 // Inter file linking and resolution.
1219 linkInterFileAndResolve();
1220
1221 addDerivedRefTypeToRefTypeResolutionList();
1222 }
1223 }
1224
1225 /**
1226 * Process x-path linking for augment and leaf-ref.
1227 *
janani bebb143d2016-07-14 19:35:22 +05301228 * @param entityToResolve entity to resolve
1229 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +05301230 */
janani bebb143d2016-07-14 19:35:22 +05301231 private void processXPathLinking(T entityToResolve,
Bharat saraswal2da23bf2016-08-25 15:28:39 +05301232 YangReferenceResolver root) {
janani bebb143d2016-07-14 19:35:22 +05301233
Bharat saraswald14cbe82016-07-14 13:26:18 +05301234 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
janani bebb143d2016-07-14 19:35:22 +05301235
Bharat saraswald14cbe82016-07-14 13:26:18 +05301236 if (entityToResolve instanceof YangAugment) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301237 YangNode targetNode = null;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301238 YangAugment augment = (YangAugment) entityToResolve;
1239 targetNode = xPathLinker.processAugmentXpathLinking(augment.getTargetNode(),
1240 (YangNode) root);
1241 if (targetNode != null) {
1242 if (targetNode instanceof YangAugmentableNode) {
1243 detectCollisionForAugmentedNode(targetNode, augment);
1244 ((YangAugmentableNode) targetNode).addAugmentation(augment);
Vidyashree Rama052ada62016-08-17 14:03:29 +05301245 ((YangAugmentableNode) targetNode).setIsAugmented(true);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301246 augment.setAugmentedNode(targetNode);
1247 Resolvable resolvable = (Resolvable) entityToResolve;
1248 resolvable.setResolvableStatus(RESOLVED);
1249 } else {
1250 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for "
1251 + augment.getName());
1252 }
1253 } else {
1254 throw new LinkerException("Failed to link " + augment.getName());
1255 }
Vidyashree Ramab3670472016-08-06 15:49:56 +05301256 } else if (entityToResolve instanceof YangCompilerAnnotation) {
1257 YangNode targetNode;
1258 YangCompilerAnnotation ca = (YangCompilerAnnotation) entityToResolve;
1259
1260 targetNode = xPathLinker.processAugmentXpathLinking(ca.getAtomicPathList(),
1261 (YangNode) root);
1262 if (targetNode != null) {
1263 if (targetNode instanceof YangList) {
1264 ((YangList) targetNode).setCompilerAnnotation(
1265 (YangCompilerAnnotation) entityToResolve);
1266 Resolvable resolvable = (Resolvable) entityToResolve;
1267 resolvable.setResolvableStatus(RESOLVED);
1268 } else {
1269 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for compiler" +
1270 " annotation " + ca.getPath());
1271 }
1272 } else {
1273 throw new LinkerException("Failed to link compiler annotation " + ca.getPath());
1274 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301275 } else if (entityToResolve instanceof YangLeafRef) {
1276 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
1277 Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
janani bebb143d2016-07-14 19:35:22 +05301278 (YangNode) root, leafRef);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301279 if (target != null) {
1280 YangLeaf leaf = null;
1281 YangLeafList leafList = null;
1282 leafRef.setReferredLeafOrLeafList(target);
1283 if (target instanceof YangLeaf) {
1284 leaf = (YangLeaf) target;
janani bebb143d2016-07-14 19:35:22 +05301285 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1286 addUnResolvedLeafRefTypeToStack((T) leaf, getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301287 } else {
1288 leafList = (YangLeafList) target;
janani bebb143d2016-07-14 19:35:22 +05301289 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1290 addUnResolvedLeafRefTypeToStack((T) leafList,
1291 getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301292 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301293 //TODO: add logic for leaf-ref for path predicates.
1294 } else {
janani bebb143d2016-07-14 19:35:22 +05301295 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
1296 "leaf/leaf-list for given leafref path "
Bharat saraswald14cbe82016-07-14 13:26:18 +05301297 + leafRef.getPath());
janani bebb143d2016-07-14 19:35:22 +05301298 linkerException.setCharPosition(leafRef.getCharPosition());
1299 linkerException.setLine(leafRef.getLineNumber());
1300 throw linkerException;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301301 }
1302 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301303 }
1304
1305 /**
1306 * Returns the referenced prefix of entity under resolution.
1307 *
1308 * @return referenced prefix of entity under resolution
1309 * @throws DataModelException a violation in data model rule
1310 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301311 private String getRefPrefix()
1312 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301313 String refPrefix;
1314 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1315 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1316 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1317 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301318 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1319 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301320 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1321 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1322 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1323 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301324 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301325 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
janani bebb143d2016-07-14 19:35:22 +05301326 "type/uses/base/identityref");
janani b0e4e8ae2016-07-13 21:06:41 +05301327 }
1328 return refPrefix;
1329 }
1330
1331 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301332 * Performs inter file linking and resolution.
1333 *
1334 * @throws DataModelException a violation in data model rule
1335 */
1336 private void linkInterFileAndResolve()
1337 throws DataModelException {
1338
1339 while (getPartialResolvedStack().size() != 0) {
1340
1341 // Current node to resolve, it can be a YANG type or YANG uses.
1342 T entityToResolve = getCurrentEntityToResolveFromStack();
1343 // Check if linking is already done
1344 if (entityToResolve instanceof Resolvable) {
1345
1346 Resolvable resolvable = (Resolvable) entityToResolve;
1347 switch (resolvable.getResolvableStatus()) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301348 case RESOLVED: {
1349 /*
1350 * If the entity is already resolved in the stack, then pop
1351 * it and continue with the remaining stack elements to
1352 * resolve
1353 */
1354 getPartialResolvedStack().pop();
1355 break;
1356 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301357
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301358 case INTER_FILE_LINKED: {
1359 /*
1360 * If the top of the stack is already linked then resolve
1361 * the references and pop the entity and continue with
1362 * remaining stack elements to resolve
1363 */
1364 resolveTopOfStack(INTER_FILE);
1365 getPartialResolvedStack().pop();
1366 break;
1367 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301368
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301369 case INTRA_FILE_RESOLVED: {
1370 /*
1371 * If the top of the stack is intra file resolved then check
1372 * if top of stack is linked, if not link it using
1373 * import/include list and push the linked referred entity
1374 * to the stack, otherwise only push it to the stack.
1375 */
1376 linkInterFileTopOfStackRefUpdateStack();
1377 break;
1378 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301379
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301380 case UNDEFINED: {
1381 /*
1382 * In case of if-feature resolution, if referred "feature" is not
1383 * defined then the resolvable status will be undefined.
1384 */
1385 getPartialResolvedStack().pop();
1386 break;
1387 }
1388
1389 default: {
1390 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1391 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301392
1393 }
1394
1395 } else {
1396 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1397 }
1398
1399 }
1400
1401 }
1402
1403 /**
1404 * Links the top of the stack if it's inter-file and update stack.
1405 *
1406 * @throws DataModelException data model error
1407 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301408 private void linkInterFileTopOfStackRefUpdateStack()
1409 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301410
janani bebb143d2016-07-14 19:35:22 +05301411 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1412 // When leafref path comes with relative path, it will be converted to absolute path.
1413 setAbsolutePathFromRelativePathInLeafref(getCurrentEntityToResolveFromStack());
1414 processXPathLinking(getCurrentEntityToResolveFromStack(), getCurReferenceResolver());
1415 return;
1416 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301417 /*
1418 * Obtain the referred node of top of stack entity under resolution
1419 */
1420 T referredNode = getRefNode();
1421
1422 /*
1423 * Check for null for scenario when it's not linked and inter-file
1424 * linking is required.
1425 */
1426 if (referredNode == null) {
1427
1428 /*
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301429 * Check if prefix is null or not, to identify whether to search in
1430 * import list or include list.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301431 */
Bharat saraswal5cd9e9c2016-05-26 23:48:38 +05301432 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301433 if (resolveWithImport()) {
1434 return;
1435 }
1436 } else {
1437 if (resolveWithInclude()) {
1438 return;
1439 }
1440 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301441
1442 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1443 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1444 return;
1445 }
janani b0e4e8ae2016-07-13 21:06:41 +05301446 // If current entity is still not resolved, then
1447 // linking/resolution has failed.
1448 String errorInfo;
1449 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1450 errorInfo = TYPEDEF_LINKER_ERROR;
1451 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1452 errorInfo = GROUPING_LINKER_ERROR;
1453 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1454 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huawei234cd092016-07-14 11:35:34 +05301455 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1456 errorInfo = BASE_LINKER_ERROR;
1457 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1458 errorInfo = IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +05301459 } else {
1460 errorInfo = LEAFREF_LINKER_ERROR;
1461 }
1462 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301463 dataModelException.setLine(getLineNumber());
1464 dataModelException.setCharPosition(getCharPosition());
1465 throw dataModelException;
1466 } else {
janani bebb143d2016-07-14 19:35:22 +05301467 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1468 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1469 }
1470 }
1471
1472 /**
1473 * Sets the leafref with absolute path from the relative path.
1474 *
1475 * @param resolutionInfo information about the YANG construct which has to be resolved
1476 * @throws DataModelException a violation of data model rules
1477 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301478 public void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo)
1479 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301480 if (resolutionInfo instanceof YangLeafRef) {
1481
1482 YangNode parentOfLeafref = ((YangLeafRef) resolutionInfo).getParentNodeOfLeafref();
1483 YangLeafRef leafref = (YangLeafRef) resolutionInfo;
1484
1485 // Checks if the leafref has relative path in it.
1486 if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
1487 YangRelativePath relativePath = leafref.getRelativePath();
1488 List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
1489 int numberOfAncestors = relativePath.getAncestorNodeCount();
1490
1491 // Gets the root node from the ancestor count.
1492 T nodeOrAugmentList = getRootNodeWithAncestorCountForLeafref(numberOfAncestors, parentOfLeafref,
1493 leafref);
1494 if (nodeOrAugmentList instanceof YangNode) {
1495 String pathNameToBePrefixed = EMPTY_STRING;
1496 YangNode rootNode = (YangNode) nodeOrAugmentList;
1497 // Forms a new absolute path from the relative path
1498 while (!(rootNode instanceof YangReferenceResolver)) {
1499 pathNameToBePrefixed = rootNode.getName() + SLASH_FOR_STRING + pathNameToBePrefixed;
1500 rootNode = rootNode.getParent();
1501 if (rootNode == null) {
1502 throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
1503 }
1504 }
1505 fillAbsolutePathValuesInLeafref(leafref, pathNameToBePrefixed, absoluteInRelative);
1506 } else {
1507 List<String> listOfAugment = (List<String>) nodeOrAugmentList;
1508 Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
1509 String augment = EMPTY_STRING;
1510 while (listOfAugmentIterator.hasNext()) {
1511 augment = augment + SLASH_FOR_STRING + listOfAugmentIterator.next();
1512 }
1513 fillAbsolutePathValuesInLeafref(leafref, augment, absoluteInRelative);
janani b0e4e8ae2016-07-13 21:06:41 +05301514 }
janani b0e4e8ae2016-07-13 21:06:41 +05301515 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301516 }
1517 }
1518
1519 /**
janani bebb143d2016-07-14 19:35:22 +05301520 * Fills the absolute path values in the leafref from relative path.
1521 *
Bharat saraswal8beac342016-08-04 02:00:03 +05301522 * @param leafref instance of YANG leafref
1523 * @param pathNameToBePrefixed path name which has to be prefixed to relative path
1524 * @param atomicPathsInRelative atomic paths in relative
janani bebb143d2016-07-14 19:35:22 +05301525 * @throws DataModelException a violation of data model rules
1526 */
1527 private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String pathNameToBePrefixed,
Bharat saraswal2da23bf2016-08-25 15:28:39 +05301528 List<YangAtomicPath> atomicPathsInRelative)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301529 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301530
1531 leafref.setPathType(YangPathArgType.ABSOLUTE_PATH);
1532 String[] pathName = new String[0];
1533 if (pathNameToBePrefixed != EMPTY_STRING && pathNameToBePrefixed != null) {
1534 pathName = pathNameToBePrefixed.split(SLASH_FOR_STRING);
1535 }
1536 List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
1537 for (String value : pathName) {
1538 if (value != null && !value.isEmpty() && value != EMPTY_STRING) {
1539 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(value, YangConstructType.PATH_DATA);
1540 YangAtomicPath atomicPath = new YangAtomicPath();
1541 atomicPath.setNodeIdentifier(nodeIdentifier);
1542 finalListForAbsolute.add(atomicPath);
1543 }
1544 }
1545 if (atomicPathsInRelative != null && !atomicPathsInRelative.isEmpty()) {
1546 Iterator<YangAtomicPath> atomicPathIterator = atomicPathsInRelative.listIterator();
1547 while (atomicPathIterator.hasNext()) {
1548 YangAtomicPath yangAtomicPath = atomicPathIterator.next();
1549 finalListForAbsolute.add(yangAtomicPath);
1550 }
1551 leafref.setAtomicPath(finalListForAbsolute);
1552 } else {
1553 DataModelException dataModelException = new DataModelException("YANG file error: The target node, in the " +
1554 "leafref path " + leafref.getPath() + ", is invalid.");
1555 dataModelException.setCharPosition(leafref.getCharPosition());
1556 dataModelException.setLine(leafref.getLineNumber());
1557 throw dataModelException;
1558 }
1559 }
1560
1561 /**
1562 * Returns the root parent with respect to the ancestor count from leafref.
1563 *
1564 * @param ancestorCount count of node where parent node can be reached
1565 * @param currentParent current parent node
1566 * @param leafref instance of YANG leafref
1567 * @return node where the ancestor count stops or augment path name list
1568 * @throws DataModelException a violation of data model rules
1569 */
1570 private T getRootNodeWithAncestorCountForLeafref(int ancestorCount, YangNode currentParent, YangLeafRef leafref)
1571 throws DataModelException {
1572
1573 int currentParentCount = 1;
1574 currentParent = skipInvalidDataNodes(currentParent, leafref);
1575 if (currentParent instanceof YangAugment) {
1576 YangAugment augment = (YangAugment) currentParent;
1577 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1578 return (T) valueInAugment;
1579 } else {
1580 while (currentParentCount < ancestorCount) {
1581 YangNode currentSkippedParent = skipInvalidDataNodes(currentParent, leafref);
1582 if (currentSkippedParent == currentParent) {
1583 if (currentParent.getParent() == null) {
1584 throw new DataModelException("YANG file error: The target node, in the leafref path "
1585 + leafref.getPath() + ", is invalid.");
1586 }
1587 currentParent = currentParent.getParent();
1588 } else {
1589 currentParent = currentSkippedParent;
1590 continue;
1591 }
1592 currentParentCount = currentParentCount + 1;
1593 if (currentParent instanceof YangAugment) {
1594 YangAugment augment = (YangAugment) currentParent;
1595 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1596 return (T) valueInAugment;
1597 }
1598 }
1599 }
1600 return (T) currentParent;
1601 }
1602
1603 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301604 * Finds and resolves with include list.
1605 *
1606 * @return true if resolved, false otherwise
1607 * @throws DataModelException a violation in data model rule
1608 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301609 private boolean resolveWithInclude()
1610 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301611 /*
1612 * Run through all the nodes in include list and search for referred
1613 * typedef/grouping at the root level.
1614 */
1615 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1616 YangNode linkedNode = null;
1617 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1618 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1619 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1620 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301621 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1622 linkedNode = findRefFeature(yangInclude.getIncludedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301623 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1624 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1625 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1626 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301627 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301628
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301629 if (linkedNode != null) {
1630 // Add the link to external entity.
1631 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301632
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301633 // Add the type/uses of referred typedef/grouping to the stack.
1634 addUnresolvedRecursiveReferenceToStack(linkedNode);
1635 return true;
1636 }
1637 }
1638 // If referred node can't be found return false.
1639 return false;
1640 }
1641
1642 /**
1643 * Finds and resolves with import list.
1644 *
1645 * @return true if resolved, false otherwise
1646 * @throws DataModelException a violation in data model rule
1647 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301648 private boolean resolveWithImport()
1649 throws DataModelException {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301650
1651 // Run through import list to find the referred typedef/grouping.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301652 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1653 /*
1654 * Match the prefix attached to entity under resolution with the
1655 * imported/included module/sub-module's prefix. If found, search
1656 * for the referred typedef/grouping at the root level.
1657 */
1658 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1659 YangNode linkedNode = null;
1660 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1661 linkedNode = findRefTypedef(yangImport.getImportedNode());
1662 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1663 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301664 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1665 linkedNode = findRefFeature(yangImport.getImportedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301666 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1667 linkedNode = findRefIdentity(yangImport.getImportedNode());
1668 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1669 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301670 }
1671 if (linkedNode != null) {
1672 // Add the link to external entity.
1673 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301674
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301675 // Add the type/uses of referred typedef/grouping to the
1676 // stack.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301677 addUnresolvedRecursiveReferenceToStack(linkedNode);
1678 return true;
1679 }
1680 /*
1681 * If referred node can't be found at root level break for loop,
1682 * and return false.
1683 */
1684 break;
1685 }
1686 }
1687 // If referred node can't be found return false.
1688 return false;
1689 }
1690
1691 /**
1692 * Returns referred typedef/grouping node.
1693 *
1694 * @return referred typedef/grouping node
1695 * @throws DataModelException a violation in data model rule
1696 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301697 private T getRefNode()
1698 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301699 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301700 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1701 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301702 return (T) derivedInfo.getReferredTypeDef();
1703 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1704 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301705 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1706 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani b0e4e8ae2016-07-13 21:06:41 +05301707 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1708 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301709 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1710 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1711 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1712 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301713 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301714 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +05301715 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301716 }
1717 }
1718
1719 /**
1720 * Finds the referred grouping node at the root level of imported/included node.
1721 *
1722 * @param refNode module/sub-module node
1723 * @return referred grouping
1724 */
1725 private YangNode findRefGrouping(YangNode refNode) {
1726 YangNode tmpNode = refNode.getChild();
1727 while (tmpNode != null) {
1728 if (tmpNode instanceof YangGrouping) {
1729 if (tmpNode.getName()
1730 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1731 return tmpNode;
1732 }
1733 }
1734 tmpNode = tmpNode.getNextSibling();
1735 }
1736 return null;
1737 }
1738
1739 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301740 * Finds the referred feature node at the root level of imported/included node.
1741 *
1742 * @param refNode module/sub-module node
1743 * @return referred feature
1744 */
1745 private YangNode findRefFeature(YangNode refNode) {
1746 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1747 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1748
1749 if (featureList != null && !featureList.isEmpty()) {
1750 Iterator<YangFeature> iterator = featureList.iterator();
1751 while (iterator.hasNext()) {
1752 YangFeature feature = iterator.next();
1753 if (ifFeature.getName().equals(feature.getName())) {
1754 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1755 return refNode;
1756 }
1757 }
1758 }
1759 return null;
1760 }
1761
1762 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301763 * Finds the referred typedef node at the root level of imported/included node.
1764 *
1765 * @param refNode module/sub-module node
1766 * @return referred typedef
1767 */
1768 private YangNode findRefTypedef(YangNode refNode) {
1769 YangNode tmpNode = refNode.getChild();
1770 while (tmpNode != null) {
1771 if (tmpNode instanceof YangTypeDef) {
1772 if (tmpNode.getName()
1773 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1774 return tmpNode;
1775 }
1776 }
1777 tmpNode = tmpNode.getNextSibling();
1778 }
1779 return null;
1780 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301781
1782 /**
1783 * Finds the referred identity node at the root level of imported/included node.
1784 *
1785 * @param refNode module/sub-module node
1786 * @return referred identity
1787 */
1788 private YangNode findRefIdentity(YangNode refNode) {
1789 YangNode tmpNode = refNode.getChild();
1790 while (tmpNode != null) {
1791 if (tmpNode instanceof YangIdentity) {
1792 if (tmpNode.getName()
1793 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1794 return tmpNode;
1795 }
1796 }
1797 tmpNode = tmpNode.getNextSibling();
1798 }
1799 return null;
1800 }
1801
1802 /**
1803 * Finds the referred identity node at the root level of imported/included node.
1804 *
1805 * @param refNode module/sub-module node
1806 * @return referred identity
1807 */
1808 private YangNode findRefIdentityRef(YangNode refNode) {
1809 YangNode tmpNode = refNode.getChild();
1810 while (tmpNode != null) {
1811 if (tmpNode instanceof YangIdentity) {
1812 if (tmpNode.getName()
1813 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
janani bebb143d2016-07-14 19:35:22 +05301814 .getBaseIdentity().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301815 return tmpNode;
1816 }
1817 }
1818 tmpNode = tmpNode.getNextSibling();
1819 }
1820 return null;
1821 }
Bharat saraswal2da23bf2016-08-25 15:28:39 +05301822
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301823}