blob: 00fb699871fd86f077c656fbec5dc9005b8afc10 [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-Huawei423dc9a2016-08-17 22:08:42 +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 saraswalc2d3be12016-06-16 00:29:12 +0530130 private transient 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);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530168 /**
169 * 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) {
178 /**
179 * 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) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530204 /**
205 * 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 /*
487 * In case prefix is not present it's a candidate for inter-file
488 * resolution via include list.
489 */
490 if (getRefPrefix() == null) {
491 ((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
Vidyashree Ramab3670472016-08-06 15:49:56 +0530528 //In case prefix is not present it's a candidate for inter-file resolution via include list.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530529 if (getRefPrefix() == null) {
530 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
531 }
532 }
533
534 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530535 * Returns the root parent with respect to the ancestor count from leafref.
536 *
537 * @param ancestorCount count of node where parent node can be reached
538 * @param currentParent current parent node
539 * @return root node
540 * @throws DataModelException a violation of data model rules
541 */
542 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
543 throws DataModelException {
544
545 int currentParentCount = 1;
546 while (currentParentCount < ancestorCount) {
547 if (currentParent.getParent() == null) {
548 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
549 }
550 currentParent = currentParent.getParent();
551 currentParentCount = currentParentCount + 1;
552 }
553 return currentParent;
554 }
555
556 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530557 * Resolves self file linking for if-feature.
558 *
559 * @param potentialAncestorWithReferredNode if-feature holder node
560 * @throws DataModelException DataModelException a violation of data model
561 * rules
562 */
563 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
564 throws DataModelException {
565
566 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
567 YangNode potentialReferredNode = (YangNode) featureHolder;
568 if (isReferredNode(potentialReferredNode)) {
569
570 // Adds reference link of entity to the node under resolution.
571 addReferredEntityLink(potentialReferredNode, LINKED);
572
573 /**
574 * resolve the reference and update the partial resolution stack
575 * with any further recursive references
576 */
577 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
578 return;
579 }
580
581 /*
582 * In case prefix is not present it's a candidate for inter-file
583 * resolution via include list.
584 */
585 if (getRefPrefix() == null) {
586 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
587 }
588 }
589
janani b0e4e8ae2016-07-13 21:06:41 +0530590 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530591 * Returns the status of the referred identity found for base/identityref.
592 *
janani bebb143d2016-07-14 19:35:22 +0530593 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
Shankara-Huawei234cd092016-07-14 11:35:34 +0530594 * @param ancestorWithTheReferredNode the parent node of base/identityref
595 * @return status of referred base/identityref
596 * @throws DataModelException a violation of data model rules
597 */
598 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
599 throws DataModelException {
600
601 // When child is not present return.
602 if (ancestorWithTheReferredNode.getChild() == null) {
603 return false;
604 }
605
606 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
607
608 // Checks all the siblings under the node and returns the matched node.
609 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
610
611 if (nodeFound != null) {
612 // Adds reference link of entity to the node under resolution.
613 addReferredEntityLink(nodeFound, LINKED);
614
615 /**
616 * resolve the reference and update the partial resolution stack with any further recursive references
617 */
618 addUnresolvedRecursiveReferenceToStack(nodeFound);
619 return true;
620 }
621
622 return false;
623 }
624
625 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530626 * Adds the unresolved constructs to stack which has to be resolved for leafref.
627 *
janani bebb143d2016-07-14 19:35:22 +0530628 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
janani b0e4e8ae2016-07-13 21:06:41 +0530629 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
630 */
631 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
632
633 YangType referredTypeInLeafOrLeafList;
634 if (yangleafOrLeafList instanceof YangLeaf) {
635 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
636 referredTypeInLeafOrLeafList = leaf.getDataType();
637 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
638 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
639 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
640 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
641 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
642 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
643 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
644 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
645 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
646 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
647 }
648 } else {
649 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
650 referredTypeInLeafOrLeafList = leafList.getDataType();
651 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
652 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
653 unResolvedEntityInfo
654 .setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
655 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
656 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
657 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
658 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
659 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
660 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
661 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
662 }
663 }
664 }
665
666 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530667 * Returns feature holder(module/sub-module node) .
668 *
669 * @param potentialAncestorWithReferredNode if-feature holder node
670 */
671 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
672 while (potentialAncestorWithReferredNode != null) {
673 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
674 return (YangFeatureHolder) potentialAncestorWithReferredNode;
675 }
676 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
677 }
678 return null;
679 }
680
681 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530682 * Checks if the reference in self file or in external file.
683 *
684 * @return true if self file reference, false otherwise
685 * @throws DataModelException a violation of data model rules
686 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530687 private boolean isCandidateForSelfFileReference()
688 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530689 String prefix = getRefPrefix();
690 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
691 }
692
693 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530694 * Checks for the referred parent node for the leafref path.
695 *
696 * @param potentialReferredNode potential referred node
697 * @return the reffered parent node of leaf/leaf-list
698 * @throws DataModelException data model errors
699 */
700 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
701 throws DataModelException {
702
703 while (potentialReferredNode != null) {
704 if (potentialReferredNode instanceof YangInput) {
705 if (referredNodeName.equalsIgnoreCase(INPUT)) {
706 return potentialReferredNode;
707 }
708 } else if (potentialReferredNode instanceof YangOutput) {
709 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
710 return potentialReferredNode;
711 }
712 }
713 // Check if the potential referred node is the actual referred node
714 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
715 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
716 if (potentialReferredNode.getParent() instanceof YangRpc) {
717 potentialReferredNode = potentialReferredNode.getNextSibling();
718 } else {
719 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
720 }
721 }
722 return potentialReferredNode;
723 }
724 potentialReferredNode = potentialReferredNode.getNextSibling();
725 }
726 return null;
727 }
728
729 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530730 * Checks for the referred parent node for the base/identity.
731 *
732 * @param potentialReferredNode potential referred node
733 * @return the reffered parent node of base/identity.
734 * @throws DataModelException data model errors
735 */
736 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530737 String referredNodeName)
738 throws DataModelException {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530739
740 while (potentialReferredNode != null) {
741 if (potentialReferredNode instanceof YangIdentity) {
742 // Check if the potential referred node is the actual referred node
743 if (isReferredNodeForIdentity(potentialReferredNode, referredNodeName)) {
744 return potentialReferredNode;
745 }
746 }
747 potentialReferredNode = potentialReferredNode.getNextSibling();
748 }
749 return null;
750 }
751
752 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530753 * Checks if the current reference node name and the name in the path are equal.
754 *
755 * @param currentReferredNode the node where the reference is pointed
janani bebb143d2016-07-14 19:35:22 +0530756 * @param nameOfNodeinPath name of the node in the path
janani b0e4e8ae2016-07-13 21:06:41 +0530757 * @return status of the match between the name
758 * @throws DataModelException a violation of data model rules
759 */
760 private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
761 throws DataModelException {
762
763 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
764 /*
765 * Check if name of node name matches with the current reference
766 * node.
767 */
768 return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
769 } else {
770 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
771 }
772 }
773
774 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530775 * Checks if the current reference node name and the name in the base/identityref base are equal.
776 *
janani bebb143d2016-07-14 19:35:22 +0530777 * @param currentReferredNode the node where the reference is pointed
Shankara-Huawei234cd092016-07-14 11:35:34 +0530778 * @param nameOfIdentityRefBase name of the base in the base/identityref base
779 * @return status of the match between the name
780 * @throws DataModelException a violation of data model rules
781 */
782 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
783 throws DataModelException {
784
785 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
786 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530787
788 //Check if name of node name matches with the current reference node.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530789 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
790 } else {
791 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref");
792 }
793 }
794
795 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530796 * Checks for the referred node defined in a ancestor scope.
797 *
798 * @param potentialReferredNode potential referred node
799 * @return status of resolution and updating the partial resolved stack with
800 * the any recursive references
janani b0e4e8ae2016-07-13 21:06:41 +0530801 * @throws DataModelException a violation of data model rules
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530802 */
803 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
804 throws DataModelException {
805 while (potentialReferredNode != null) {
806
807 // Check if the potential referred node is the actual referred node
808 if (isReferredNode(potentialReferredNode)) {
809
810 // Adds reference link of entity to the node under resolution.
811 addReferredEntityLink(potentialReferredNode, LINKED);
812
813 /**
814 * resolve the reference and update the partial resolution stack
815 * with any further recursive references
816 */
817 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
818
819 /*
820 * return true, since the reference is linked and any recursive
821 * unresolved references is added to the stack
822 */
823 return true;
824 }
825
826 potentialReferredNode = potentialReferredNode.getNextSibling();
827 }
828 return false;
829 }
830
831 /**
832 * Checks if the potential referred node is the actual referred node.
833 *
834 * @param potentialReferredNode typedef/grouping node
835 * @return true if node is of resolve type otherwise false
836 * @throws DataModelException a violation of data model rules
837 */
838 private boolean isReferredNode(YangNode potentialReferredNode)
839 throws DataModelException {
840 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
841 if (potentialReferredNode instanceof YangTypeDef) {
842 /*
843 * Check if name of node name matches with the entity being
844 * resolved
845 */
846 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
847 }
848 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
849 if (potentialReferredNode instanceof YangGrouping) {
850 /*
851 * Check if name of node name matches with the entity being
852 * resolved
853 */
854 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
855 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530856 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
857 if (potentialReferredNode instanceof YangFeatureHolder) {
858 /*
859 * Check if name of node name matches with the entity being
860 * resolved
861 */
862 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
863 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530864 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
865 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
866 if (potentialReferredNode instanceof YangIdentity) {
867 /*
868 * Check if name of node name matches with the entity being
869 * resolved
870 */
871 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
872 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530873 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530874 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
janani bebb143d2016-07-14 19:35:22 +0530875 "uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530876 }
877 return false;
878 }
879
880 /**
881 * Checks if node name is same as name in resolution info, i.e. name of
882 * typedef/grouping is same as name of type/uses.
883 *
884 * @param node typedef/grouping node
885 * @return true if node name is same as name in resolution info, otherwise
886 * false
887 * @throws DataModelException a violation of data model rules
888 */
889
890 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
891 throws DataModelException {
892 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
893 if (node.getName().contentEquals(
894 ((YangType<?>) getCurrentEntityToResolveFromStack())
895 .getDataTypeName())) {
896 return true;
897 }
898 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
899 if (node.getName().contentEquals(
900 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
901 return true;
902 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530903 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
904 return isFeatureDefinedInNode(node);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530905 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
906 if (node.getName().contentEquals(
907 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
908 return true;
909 }
910 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
911 if (node.getName().contentEquals(
912 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
913 return true;
914 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530915 } else {
916 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
917 }
918 return false;
919 }
920
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530921 private boolean isFeatureDefinedInNode(YangNode node)
922 throws DataModelException {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530923 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
924 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
925 if (featureList != null && !featureList.isEmpty()) {
926 Iterator<YangFeature> iterator = featureList.iterator();
927 while (iterator.hasNext()) {
928 YangFeature feature = iterator.next();
929 if (ifFeature.getName().equals(feature.getName())) {
930 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
931 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
932 return true;
933 }
934 }
935 }
936 return false;
937 }
938
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530939 /**
940 * Adds reference of grouping/typedef in uses/type.
941 *
942 * @param referredNode grouping/typedef node being referred
943 * @param linkedStatus linked status if success.
944 * @throws DataModelException a violation of data model rules
945 */
946 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
947 throws DataModelException {
948 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530949 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
950 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530951 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
952 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
953 ((YangUses) getCurrentEntityToResolveFromStack())
954 .setRefGroup((YangGrouping) referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530955 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
956 // do nothing , referred node is already set
janani b0e4e8ae2016-07-13 21:06:41 +0530957 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
958 // do nothing , referred node is already set
Shankara-Huawei234cd092016-07-14 11:35:34 +0530959 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
960 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
961 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
962 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530963 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530964 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +0530965 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530966 }
967
968 // Sets the resolution status in inside the type/uses.
969 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
970 }
971
972 /**
973 * Checks if type/grouping has further reference to typedef/ unresolved
974 * uses. Add it to the partial resolve stack and return the status of
975 * addition to stack.
976 *
977 * @param referredNode grouping/typedef node
978 * @throws DataModelException a violation of data model rules
979 */
980 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
981 throws DataModelException {
982 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530983
984 //Checks if typedef type is derived
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530985 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530986
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530987 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530988 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
989 .getTypeDefBaseType());
990 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530991 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530992 }
993
994 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
995 /*
996 * Search if the grouping has any un resolved uses child, if so
997 * return true, else return false.
998 */
999 addUnResolvedUsesToStack(referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301000 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1001 addUnResolvedIfFeatureToStack(referredNode);
janani b0e4e8ae2016-07-13 21:06:41 +05301002 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1003 // do nothing , referred node is already set
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301004 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
Shankara-Huawei234cd092016-07-14 11:35:34 +05301005 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1006 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301007
1008 //Search if the identity has any un resolved base, if so return true, else return false.
Shankara-Huawei234cd092016-07-14 11:35:34 +05301009 addUnResolvedBaseToStack(referredNode);
1010 } else {
1011 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
janani bebb143d2016-07-14 19:35:22 +05301012 "base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301013 }
1014 }
1015
1016 /**
1017 * Returns if there is any unresolved uses in grouping.
1018 *
1019 * @param node grouping/typedef node
1020 */
1021 private void addUnResolvedUsesToStack(YangNode node) {
1022
Vidyashree Ramab3670472016-08-06 15:49:56 +05301023 //Search the grouping node's children for presence of uses node.
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301024 TraversalType curTraversal = ROOT;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301025 YangNode curNode = node.getChild();
1026 while (curNode != null) {
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301027 if (curNode.getName().equals(node.getName())) {
1028 // if we have traversed all the child nodes, then exit from loop
1029 return;
1030 }
1031
1032 // if child nodes has uses, then add it to resolution stack
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301033 if (curNode instanceof YangUses) {
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301034 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301035 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1036 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301037 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301038 }
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301039
1040 // Traversing all the child nodes of grouping
1041 if (curTraversal != PARENT && curNode.getChild() != null) {
1042 curTraversal = CHILD;
1043 curNode = curNode.getChild();
1044 } else if (curNode.getNextSibling() != null) {
1045 curTraversal = SIBILING;
1046 curNode = curNode.getNextSibling();
1047 } else {
1048 curTraversal = PARENT;
1049 curNode = curNode.getParent();
1050 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301051 }
1052 }
1053
1054 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301055 * Returns if there is any unresolved if-feature in feature.
1056 *
1057 * @param node module/submodule node
1058 */
1059 private void addUnResolvedIfFeatureToStack(YangNode node) {
1060 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1061 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1062 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1063 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1064 while (ifFeatureIterator.hasNext()) {
1065 YangIfFeature ifFeature = ifFeatureIterator.next();
1066 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1067 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1068 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1069 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1070 }
1071 }
1072 }
1073
1074 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +05301075 * Returns if there is any unresolved base in identity.
1076 *
1077 * @param node module/submodule node
1078 */
1079 private void addUnResolvedBaseToStack(YangNode node) {
1080
1081 YangIdentity curNode = (YangIdentity) node;
1082 if (curNode.getBaseNode() != null) {
1083 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1084 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1085 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1086 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1087 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1088
1089 }
1090 }
1091 }
1092
1093
1094 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301095 * Returns stack of YANG type with partially resolved YANG construct
1096 * hierarchy.
1097 *
1098 * @return partial resolved YANG construct stack
1099 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301100 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301101 return partialResolvedStack;
1102 }
1103
1104 /**
1105 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1106 *
1107 * @param partialResolvedStack partial resolved YANG construct stack
1108 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301109 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301110 this.partialResolvedStack = partialResolvedStack;
1111 }
1112
1113 /**
1114 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1115 *
1116 * @param partialResolvedInfo partial resolved YANG construct stack
1117 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301118 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301119 getPartialResolvedStack().push(partialResolvedInfo);
1120 }
1121
1122 /**
1123 * Retrieves the next entity in the stack that needs to be resolved. It is
1124 * assumed that the caller ensures that the stack is not empty.
1125 *
1126 * @return next entity in the stack that needs to be resolved
1127 */
1128 private T getCurrentEntityToResolveFromStack() {
1129 return getPartialResolvedStack().peek().getEntityToResolve();
1130 }
1131
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301132 @Override
1133 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301134 return entityToResolveInfo;
1135 }
1136
1137 /**
1138 * Sets information about the entity that needs to be resolved.
1139 *
1140 * @param entityToResolveInfo information about the entity that needs to be
1141 * resolved
1142 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301143 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301144 this.entityToResolveInfo = entityToResolveInfo;
1145 }
1146
1147 @Override
1148 public int getLineNumber() {
1149 return lineNumber;
1150 }
1151
1152 @Override
1153 public int getCharPosition() {
1154 return charPosition;
1155 }
1156
1157 @Override
1158 public void setLineNumber(int lineNumber) {
1159 this.lineNumber = lineNumber;
1160 }
1161
1162 @Override
1163 public void setCharPosition(int charPositionInLine) {
1164 this.charPosition = charPositionInLine;
1165 }
1166
1167 /**
1168 * Returns current module/sub-module reference, will be used in inter-file/
1169 * inter-jar scenario to get the import/include list.
1170 *
1171 * @return current module/sub-module reference
1172 */
1173 private YangReferenceResolver getCurReferenceResolver() {
1174 return curReferenceResolver;
1175 }
1176
1177 /**
1178 * Sets current module/sub-module reference, will be used in inter-file/
1179 * inter-jar scenario to get the import/include list.
1180 *
1181 * @param curReferenceResolver current module/sub-module reference
1182 */
1183 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1184 this.curReferenceResolver = curReferenceResolver;
1185 }
1186
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301187 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301188 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1189 throws DataModelException {
1190
1191 setCurReferenceResolver(dataModelRootNode);
1192
1193 // Current node to resolve, it can be a YANG type or YANG uses.
1194 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1195
1196 // Check if linking is already done
1197 if (entityToResolve instanceof Resolvable) {
1198 Resolvable resolvable = (Resolvable) entityToResolve;
1199 if (resolvable.getResolvableStatus() == RESOLVED) {
1200 return;
1201 }
1202 } else {
1203 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1204 }
1205
janani bebb143d2016-07-14 19:35:22 +05301206 if (entityToResolve instanceof YangXPathResolver && !(entityToResolve instanceof YangLeafRef)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +05301207 //Process x-path linking.
janani bebb143d2016-07-14 19:35:22 +05301208 processXPathLinking(entityToResolve, dataModelRootNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301209
Bharat saraswald14cbe82016-07-14 13:26:18 +05301210 } else {
janani b0e4e8ae2016-07-13 21:06:41 +05301211
Bharat saraswald14cbe82016-07-14 13:26:18 +05301212 // Push the initial entity to resolve in stack.
1213 addInPartialResolvedStack(getEntityToResolveInfo());
1214
1215 // Inter file linking and resolution.
1216 linkInterFileAndResolve();
1217
1218 addDerivedRefTypeToRefTypeResolutionList();
1219 }
1220 }
1221
1222 /**
1223 * Process x-path linking for augment and leaf-ref.
1224 *
janani bebb143d2016-07-14 19:35:22 +05301225 * @param entityToResolve entity to resolve
1226 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +05301227 */
janani bebb143d2016-07-14 19:35:22 +05301228 private void processXPathLinking(T entityToResolve,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301229 YangReferenceResolver root) {
janani bebb143d2016-07-14 19:35:22 +05301230
Bharat saraswald14cbe82016-07-14 13:26:18 +05301231 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
janani bebb143d2016-07-14 19:35:22 +05301232
Bharat saraswald14cbe82016-07-14 13:26:18 +05301233 if (entityToResolve instanceof YangAugment) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301234 YangNode targetNode = null;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301235 YangAugment augment = (YangAugment) entityToResolve;
1236 targetNode = xPathLinker.processAugmentXpathLinking(augment.getTargetNode(),
1237 (YangNode) root);
1238 if (targetNode != null) {
1239 if (targetNode instanceof YangAugmentableNode) {
1240 detectCollisionForAugmentedNode(targetNode, augment);
1241 ((YangAugmentableNode) targetNode).addAugmentation(augment);
Vidyashree Rama052ada62016-08-17 14:03:29 +05301242 ((YangAugmentableNode) targetNode).setIsAugmented(true);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301243 augment.setAugmentedNode(targetNode);
1244 Resolvable resolvable = (Resolvable) entityToResolve;
1245 resolvable.setResolvableStatus(RESOLVED);
1246 } else {
1247 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for "
1248 + augment.getName());
1249 }
1250 } else {
1251 throw new LinkerException("Failed to link " + augment.getName());
1252 }
Vidyashree Ramab3670472016-08-06 15:49:56 +05301253 } else if (entityToResolve instanceof YangCompilerAnnotation) {
1254 YangNode targetNode;
1255 YangCompilerAnnotation ca = (YangCompilerAnnotation) entityToResolve;
1256
1257 targetNode = xPathLinker.processAugmentXpathLinking(ca.getAtomicPathList(),
1258 (YangNode) root);
1259 if (targetNode != null) {
1260 if (targetNode instanceof YangList) {
1261 ((YangList) targetNode).setCompilerAnnotation(
1262 (YangCompilerAnnotation) entityToResolve);
1263 Resolvable resolvable = (Resolvable) entityToResolve;
1264 resolvable.setResolvableStatus(RESOLVED);
1265 } else {
1266 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for compiler" +
1267 " annotation " + ca.getPath());
1268 }
1269 } else {
1270 throw new LinkerException("Failed to link compiler annotation " + ca.getPath());
1271 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301272 } else if (entityToResolve instanceof YangLeafRef) {
1273 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
1274 Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
janani bebb143d2016-07-14 19:35:22 +05301275 (YangNode) root, leafRef);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301276 if (target != null) {
1277 YangLeaf leaf = null;
1278 YangLeafList leafList = null;
1279 leafRef.setReferredLeafOrLeafList(target);
1280 if (target instanceof YangLeaf) {
1281 leaf = (YangLeaf) target;
janani bebb143d2016-07-14 19:35:22 +05301282 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1283 addUnResolvedLeafRefTypeToStack((T) leaf, getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301284 } else {
1285 leafList = (YangLeafList) target;
janani bebb143d2016-07-14 19:35:22 +05301286 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1287 addUnResolvedLeafRefTypeToStack((T) leafList,
1288 getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301289 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301290 //TODO: add logic for leaf-ref for path predicates.
1291 } else {
janani bebb143d2016-07-14 19:35:22 +05301292 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
1293 "leaf/leaf-list for given leafref path "
Bharat saraswald14cbe82016-07-14 13:26:18 +05301294 + leafRef.getPath());
janani bebb143d2016-07-14 19:35:22 +05301295 linkerException.setCharPosition(leafRef.getCharPosition());
1296 linkerException.setLine(leafRef.getLineNumber());
1297 throw linkerException;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301298 }
1299 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301300 }
1301
1302 /**
1303 * Returns the referenced prefix of entity under resolution.
1304 *
1305 * @return referenced prefix of entity under resolution
1306 * @throws DataModelException a violation in data model rule
1307 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301308 private String getRefPrefix()
1309 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301310 String refPrefix;
1311 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1312 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1313 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1314 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301315 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1316 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301317 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1318 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1319 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1320 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301321 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301322 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
janani bebb143d2016-07-14 19:35:22 +05301323 "type/uses/base/identityref");
janani b0e4e8ae2016-07-13 21:06:41 +05301324 }
1325 return refPrefix;
1326 }
1327
1328 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301329 * Performs inter file linking and resolution.
1330 *
1331 * @throws DataModelException a violation in data model rule
1332 */
1333 private void linkInterFileAndResolve()
1334 throws DataModelException {
1335
1336 while (getPartialResolvedStack().size() != 0) {
1337
1338 // Current node to resolve, it can be a YANG type or YANG uses.
1339 T entityToResolve = getCurrentEntityToResolveFromStack();
1340 // Check if linking is already done
1341 if (entityToResolve instanceof Resolvable) {
1342
1343 Resolvable resolvable = (Resolvable) entityToResolve;
1344 switch (resolvable.getResolvableStatus()) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301345 case RESOLVED: {
1346 /*
1347 * If the entity is already resolved in the stack, then pop
1348 * it and continue with the remaining stack elements to
1349 * resolve
1350 */
1351 getPartialResolvedStack().pop();
1352 break;
1353 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301354
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301355 case INTER_FILE_LINKED: {
1356 /*
1357 * If the top of the stack is already linked then resolve
1358 * the references and pop the entity and continue with
1359 * remaining stack elements to resolve
1360 */
1361 resolveTopOfStack(INTER_FILE);
1362 getPartialResolvedStack().pop();
1363 break;
1364 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301365
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301366 case INTRA_FILE_RESOLVED: {
1367 /*
1368 * If the top of the stack is intra file resolved then check
1369 * if top of stack is linked, if not link it using
1370 * import/include list and push the linked referred entity
1371 * to the stack, otherwise only push it to the stack.
1372 */
1373 linkInterFileTopOfStackRefUpdateStack();
1374 break;
1375 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301376
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301377 case UNDEFINED: {
1378 /*
1379 * In case of if-feature resolution, if referred "feature" is not
1380 * defined then the resolvable status will be undefined.
1381 */
1382 getPartialResolvedStack().pop();
1383 break;
1384 }
1385
1386 default: {
1387 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1388 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301389
1390 }
1391
1392 } else {
1393 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1394 }
1395
1396 }
1397
1398 }
1399
1400 /**
1401 * Links the top of the stack if it's inter-file and update stack.
1402 *
1403 * @throws DataModelException data model error
1404 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301405 private void linkInterFileTopOfStackRefUpdateStack()
1406 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301407
janani bebb143d2016-07-14 19:35:22 +05301408 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1409 // When leafref path comes with relative path, it will be converted to absolute path.
1410 setAbsolutePathFromRelativePathInLeafref(getCurrentEntityToResolveFromStack());
1411 processXPathLinking(getCurrentEntityToResolveFromStack(), getCurReferenceResolver());
1412 return;
1413 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301414 /*
1415 * Obtain the referred node of top of stack entity under resolution
1416 */
1417 T referredNode = getRefNode();
1418
1419 /*
1420 * Check for null for scenario when it's not linked and inter-file
1421 * linking is required.
1422 */
1423 if (referredNode == null) {
1424
1425 /*
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301426 * Check if prefix is null or not, to identify whether to search in
1427 * import list or include list.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301428 */
Bharat saraswal5cd9e9c2016-05-26 23:48:38 +05301429 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301430 if (resolveWithImport()) {
1431 return;
1432 }
1433 } else {
1434 if (resolveWithInclude()) {
1435 return;
1436 }
1437 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301438
1439 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1440 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1441 return;
1442 }
janani b0e4e8ae2016-07-13 21:06:41 +05301443 // If current entity is still not resolved, then
1444 // linking/resolution has failed.
1445 String errorInfo;
1446 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1447 errorInfo = TYPEDEF_LINKER_ERROR;
1448 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1449 errorInfo = GROUPING_LINKER_ERROR;
1450 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1451 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huawei234cd092016-07-14 11:35:34 +05301452 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1453 errorInfo = BASE_LINKER_ERROR;
1454 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1455 errorInfo = IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +05301456 } else {
1457 errorInfo = LEAFREF_LINKER_ERROR;
1458 }
1459 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301460 dataModelException.setLine(getLineNumber());
1461 dataModelException.setCharPosition(getCharPosition());
1462 throw dataModelException;
1463 } else {
janani bebb143d2016-07-14 19:35:22 +05301464 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1465 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1466 }
1467 }
1468
1469 /**
1470 * Sets the leafref with absolute path from the relative path.
1471 *
1472 * @param resolutionInfo information about the YANG construct which has to be resolved
1473 * @throws DataModelException a violation of data model rules
1474 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301475 public void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo)
1476 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301477 if (resolutionInfo instanceof YangLeafRef) {
1478
1479 YangNode parentOfLeafref = ((YangLeafRef) resolutionInfo).getParentNodeOfLeafref();
1480 YangLeafRef leafref = (YangLeafRef) resolutionInfo;
1481
1482 // Checks if the leafref has relative path in it.
1483 if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
1484 YangRelativePath relativePath = leafref.getRelativePath();
1485 List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
1486 int numberOfAncestors = relativePath.getAncestorNodeCount();
1487
1488 // Gets the root node from the ancestor count.
1489 T nodeOrAugmentList = getRootNodeWithAncestorCountForLeafref(numberOfAncestors, parentOfLeafref,
1490 leafref);
1491 if (nodeOrAugmentList instanceof YangNode) {
1492 String pathNameToBePrefixed = EMPTY_STRING;
1493 YangNode rootNode = (YangNode) nodeOrAugmentList;
1494 // Forms a new absolute path from the relative path
1495 while (!(rootNode instanceof YangReferenceResolver)) {
1496 pathNameToBePrefixed = rootNode.getName() + SLASH_FOR_STRING + pathNameToBePrefixed;
1497 rootNode = rootNode.getParent();
1498 if (rootNode == null) {
1499 throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
1500 }
1501 }
1502 fillAbsolutePathValuesInLeafref(leafref, pathNameToBePrefixed, absoluteInRelative);
1503 } else {
1504 List<String> listOfAugment = (List<String>) nodeOrAugmentList;
1505 Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
1506 String augment = EMPTY_STRING;
1507 while (listOfAugmentIterator.hasNext()) {
1508 augment = augment + SLASH_FOR_STRING + listOfAugmentIterator.next();
1509 }
1510 fillAbsolutePathValuesInLeafref(leafref, augment, absoluteInRelative);
janani b0e4e8ae2016-07-13 21:06:41 +05301511 }
janani b0e4e8ae2016-07-13 21:06:41 +05301512 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301513 }
1514 }
1515
1516 /**
janani bebb143d2016-07-14 19:35:22 +05301517 * Fills the absolute path values in the leafref from relative path.
1518 *
Bharat saraswal8beac342016-08-04 02:00:03 +05301519 * @param leafref instance of YANG leafref
1520 * @param pathNameToBePrefixed path name which has to be prefixed to relative path
1521 * @param atomicPathsInRelative atomic paths in relative
janani bebb143d2016-07-14 19:35:22 +05301522 * @throws DataModelException a violation of data model rules
1523 */
1524 private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String pathNameToBePrefixed,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301525 List<YangAtomicPath> atomicPathsInRelative)
1526 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301527
1528 leafref.setPathType(YangPathArgType.ABSOLUTE_PATH);
1529 String[] pathName = new String[0];
1530 if (pathNameToBePrefixed != EMPTY_STRING && pathNameToBePrefixed != null) {
1531 pathName = pathNameToBePrefixed.split(SLASH_FOR_STRING);
1532 }
1533 List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
1534 for (String value : pathName) {
1535 if (value != null && !value.isEmpty() && value != EMPTY_STRING) {
1536 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(value, YangConstructType.PATH_DATA);
1537 YangAtomicPath atomicPath = new YangAtomicPath();
1538 atomicPath.setNodeIdentifier(nodeIdentifier);
1539 finalListForAbsolute.add(atomicPath);
1540 }
1541 }
1542 if (atomicPathsInRelative != null && !atomicPathsInRelative.isEmpty()) {
1543 Iterator<YangAtomicPath> atomicPathIterator = atomicPathsInRelative.listIterator();
1544 while (atomicPathIterator.hasNext()) {
1545 YangAtomicPath yangAtomicPath = atomicPathIterator.next();
1546 finalListForAbsolute.add(yangAtomicPath);
1547 }
1548 leafref.setAtomicPath(finalListForAbsolute);
1549 } else {
1550 DataModelException dataModelException = new DataModelException("YANG file error: The target node, in the " +
1551 "leafref path " + leafref.getPath() + ", is invalid.");
1552 dataModelException.setCharPosition(leafref.getCharPosition());
1553 dataModelException.setLine(leafref.getLineNumber());
1554 throw dataModelException;
1555 }
1556 }
1557
1558 /**
1559 * Returns the root parent with respect to the ancestor count from leafref.
1560 *
1561 * @param ancestorCount count of node where parent node can be reached
1562 * @param currentParent current parent node
1563 * @param leafref instance of YANG leafref
1564 * @return node where the ancestor count stops or augment path name list
1565 * @throws DataModelException a violation of data model rules
1566 */
1567 private T getRootNodeWithAncestorCountForLeafref(int ancestorCount, YangNode currentParent, YangLeafRef leafref)
1568 throws DataModelException {
1569
1570 int currentParentCount = 1;
1571 currentParent = skipInvalidDataNodes(currentParent, leafref);
1572 if (currentParent instanceof YangAugment) {
1573 YangAugment augment = (YangAugment) currentParent;
1574 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1575 return (T) valueInAugment;
1576 } else {
1577 while (currentParentCount < ancestorCount) {
1578 YangNode currentSkippedParent = skipInvalidDataNodes(currentParent, leafref);
1579 if (currentSkippedParent == currentParent) {
1580 if (currentParent.getParent() == null) {
1581 throw new DataModelException("YANG file error: The target node, in the leafref path "
1582 + leafref.getPath() + ", is invalid.");
1583 }
1584 currentParent = currentParent.getParent();
1585 } else {
1586 currentParent = currentSkippedParent;
1587 continue;
1588 }
1589 currentParentCount = currentParentCount + 1;
1590 if (currentParent instanceof YangAugment) {
1591 YangAugment augment = (YangAugment) currentParent;
1592 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1593 return (T) valueInAugment;
1594 }
1595 }
1596 }
1597 return (T) currentParent;
1598 }
1599
1600 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301601 * Finds and resolves with include list.
1602 *
1603 * @return true if resolved, false otherwise
1604 * @throws DataModelException a violation in data model rule
1605 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301606 private boolean resolveWithInclude()
1607 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301608 /*
1609 * Run through all the nodes in include list and search for referred
1610 * typedef/grouping at the root level.
1611 */
1612 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1613 YangNode linkedNode = null;
1614 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1615 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1616 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1617 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301618 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1619 linkedNode = findRefFeature(yangInclude.getIncludedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301620 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1621 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1622 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1623 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301624 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301625
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301626 if (linkedNode != null) {
1627 // Add the link to external entity.
1628 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301629
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301630 // Add the type/uses of referred typedef/grouping to the stack.
1631 addUnresolvedRecursiveReferenceToStack(linkedNode);
1632 return true;
1633 }
1634 }
1635 // If referred node can't be found return false.
1636 return false;
1637 }
1638
1639 /**
1640 * Finds and resolves with import list.
1641 *
1642 * @return true if resolved, false otherwise
1643 * @throws DataModelException a violation in data model rule
1644 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301645 private boolean resolveWithImport()
1646 throws DataModelException {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301647
1648 // Run through import list to find the referred typedef/grouping.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301649 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1650 /*
1651 * Match the prefix attached to entity under resolution with the
1652 * imported/included module/sub-module's prefix. If found, search
1653 * for the referred typedef/grouping at the root level.
1654 */
1655 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1656 YangNode linkedNode = null;
1657 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1658 linkedNode = findRefTypedef(yangImport.getImportedNode());
1659 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1660 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301661 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1662 linkedNode = findRefFeature(yangImport.getImportedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301663 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1664 linkedNode = findRefIdentity(yangImport.getImportedNode());
1665 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1666 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301667 }
1668 if (linkedNode != null) {
1669 // Add the link to external entity.
1670 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301671
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301672 // Add the type/uses of referred typedef/grouping to the
1673 // stack.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301674 addUnresolvedRecursiveReferenceToStack(linkedNode);
1675 return true;
1676 }
1677 /*
1678 * If referred node can't be found at root level break for loop,
1679 * and return false.
1680 */
1681 break;
1682 }
1683 }
1684 // If referred node can't be found return false.
1685 return false;
1686 }
1687
1688 /**
1689 * Returns referred typedef/grouping node.
1690 *
1691 * @return referred typedef/grouping node
1692 * @throws DataModelException a violation in data model rule
1693 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301694 private T getRefNode()
1695 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301696 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301697 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1698 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301699 return (T) derivedInfo.getReferredTypeDef();
1700 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1701 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301702 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1703 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani b0e4e8ae2016-07-13 21:06:41 +05301704 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1705 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301706 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1707 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1708 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1709 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301710 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301711 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +05301712 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301713 }
1714 }
1715
1716 /**
1717 * Finds the referred grouping node at the root level of imported/included node.
1718 *
1719 * @param refNode module/sub-module node
1720 * @return referred grouping
1721 */
1722 private YangNode findRefGrouping(YangNode refNode) {
1723 YangNode tmpNode = refNode.getChild();
1724 while (tmpNode != null) {
1725 if (tmpNode instanceof YangGrouping) {
1726 if (tmpNode.getName()
1727 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1728 return tmpNode;
1729 }
1730 }
1731 tmpNode = tmpNode.getNextSibling();
1732 }
1733 return null;
1734 }
1735
1736 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301737 * Finds the referred feature node at the root level of imported/included node.
1738 *
1739 * @param refNode module/sub-module node
1740 * @return referred feature
1741 */
1742 private YangNode findRefFeature(YangNode refNode) {
1743 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1744 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1745
1746 if (featureList != null && !featureList.isEmpty()) {
1747 Iterator<YangFeature> iterator = featureList.iterator();
1748 while (iterator.hasNext()) {
1749 YangFeature feature = iterator.next();
1750 if (ifFeature.getName().equals(feature.getName())) {
1751 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1752 return refNode;
1753 }
1754 }
1755 }
1756 return null;
1757 }
1758
1759 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301760 * Finds the referred typedef node at the root level of imported/included node.
1761 *
1762 * @param refNode module/sub-module node
1763 * @return referred typedef
1764 */
1765 private YangNode findRefTypedef(YangNode refNode) {
1766 YangNode tmpNode = refNode.getChild();
1767 while (tmpNode != null) {
1768 if (tmpNode instanceof YangTypeDef) {
1769 if (tmpNode.getName()
1770 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1771 return tmpNode;
1772 }
1773 }
1774 tmpNode = tmpNode.getNextSibling();
1775 }
1776 return null;
1777 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301778
1779 /**
1780 * Finds the referred identity node at the root level of imported/included node.
1781 *
1782 * @param refNode module/sub-module node
1783 * @return referred identity
1784 */
1785 private YangNode findRefIdentity(YangNode refNode) {
1786 YangNode tmpNode = refNode.getChild();
1787 while (tmpNode != null) {
1788 if (tmpNode instanceof YangIdentity) {
1789 if (tmpNode.getName()
1790 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1791 return tmpNode;
1792 }
1793 }
1794 tmpNode = tmpNode.getNextSibling();
1795 }
1796 return null;
1797 }
1798
1799 /**
1800 * Finds the referred identity node at the root level of imported/included node.
1801 *
1802 * @param refNode module/sub-module node
1803 * @return referred identity
1804 */
1805 private YangNode findRefIdentityRef(YangNode refNode) {
1806 YangNode tmpNode = refNode.getChild();
1807 while (tmpNode != null) {
1808 if (tmpNode instanceof YangIdentity) {
1809 if (tmpNode.getName()
1810 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
janani bebb143d2016-07-14 19:35:22 +05301811 .getBaseIdentity().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301812 return tmpNode;
1813 }
1814 }
1815 tmpNode = tmpNode.getNextSibling();
1816 }
1817 return null;
1818 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301819}