blob: 8f7a08af06ed05b2600372348580082bd25d96ae [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;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053024import org.onosproject.yangutils.datamodel.Resolvable;
janani b0e4e8ae2016-07-13 21:06:41 +053025import org.onosproject.yangutils.datamodel.ResolvableType;
Vidyashree Rama72719fa2016-07-15 14:06:56 +053026import org.onosproject.yangutils.datamodel.TraversalType;
janani b0e4e8ae2016-07-13 21:06:41 +053027import org.onosproject.yangutils.datamodel.YangAtomicPath;
Bharat saraswald14cbe82016-07-14 13:26:18 +053028import org.onosproject.yangutils.datamodel.YangAugment;
29import org.onosproject.yangutils.datamodel.YangAugmentableNode;
Shankara-Huawei234cd092016-07-14 11:35:34 +053030import org.onosproject.yangutils.datamodel.YangBase;
Vidyashree Ramab3670472016-08-06 15:49:56 +053031import org.onosproject.yangutils.datamodel.YangCompilerAnnotation;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053032import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053033import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
janani bebb143d2016-07-14 19:35:22 +053034import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053035import org.onosproject.yangutils.datamodel.YangFeature;
36import org.onosproject.yangutils.datamodel.YangFeatureHolder;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053037import org.onosproject.yangutils.datamodel.YangGrouping;
Shankara-Huawei234cd092016-07-14 11:35:34 +053038import org.onosproject.yangutils.datamodel.YangIdentity;
39import org.onosproject.yangutils.datamodel.YangIdentityRef;
Bharat saraswalaf413b82016-07-14 15:18:20 +053040import org.onosproject.yangutils.datamodel.YangIfFeature;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053041import org.onosproject.yangutils.datamodel.YangImport;
42import org.onosproject.yangutils.datamodel.YangInclude;
janani b0e4e8ae2016-07-13 21:06:41 +053043import org.onosproject.yangutils.datamodel.YangInput;
44import org.onosproject.yangutils.datamodel.YangLeaf;
45import org.onosproject.yangutils.datamodel.YangLeafList;
46import org.onosproject.yangutils.datamodel.YangLeafRef;
Vidyashree Ramab3670472016-08-06 15:49:56 +053047import org.onosproject.yangutils.datamodel.YangList;
janani b0e4e8ae2016-07-13 21:06:41 +053048import org.onosproject.yangutils.datamodel.YangModule;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053049import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053050import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
janani b0e4e8ae2016-07-13 21:06:41 +053051import org.onosproject.yangutils.datamodel.YangOutput;
52import org.onosproject.yangutils.datamodel.YangPathArgType;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053053import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani b0e4e8ae2016-07-13 21:06:41 +053054import org.onosproject.yangutils.datamodel.YangRelativePath;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053055import org.onosproject.yangutils.datamodel.YangResolutionInfo;
janani b0e4e8ae2016-07-13 21:06:41 +053056import org.onosproject.yangutils.datamodel.YangRpc;
57import org.onosproject.yangutils.datamodel.YangSubModule;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053058import org.onosproject.yangutils.datamodel.YangType;
59import org.onosproject.yangutils.datamodel.YangTypeDef;
60import org.onosproject.yangutils.datamodel.YangUses;
Bharat saraswald14cbe82016-07-14 13:26:18 +053061import org.onosproject.yangutils.datamodel.YangXPathResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053062import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053063import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
janani bebb143d2016-07-14 19:35:22 +053064import org.onosproject.yangutils.datamodel.utils.YangConstructType;
janani b0e4e8ae2016-07-13 21:06:41 +053065import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +053066import org.onosproject.yangutils.linker.YangLinkingPhase;
Bharat saraswald14cbe82016-07-14 13:26:18 +053067import org.onosproject.yangutils.linker.exceptions.LinkerException;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053068
Vidyashree Rama72719fa2016-07-15 14:06:56 +053069import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
70import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
71import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
72import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
janani bebb143d2016-07-14 19:35:22 +053073import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053074import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
75import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
76import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
77import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053078import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNDEFINED;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053079import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +053080import static org.onosproject.yangutils.linker.YangLinkingPhase.INTER_FILE;
81import static org.onosproject.yangutils.linker.YangLinkingPhase.INTRA_FILE;
Bharat saraswald14cbe82016-07-14 13:26:18 +053082import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
janani bebb143d2016-07-14 19:35:22 +053083import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
84import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getValidNodeIdentifier;
85import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.skipInvalidDataNodes;
Bharat saraswalaf413b82016-07-14 15:18:20 +053086import static org.onosproject.yangutils.utils.UtilConstants.BASE_LINKER_ERROR;
janani bebb143d2016-07-14 19:35:22 +053087import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053088import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
Vidyashree Rama5daea742016-05-20 16:29:25 +053089import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
Bharat saraswalaf413b82016-07-14 15:18:20 +053090import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
91import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +053092import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
93import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
94import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
95import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
janani bebb143d2016-07-14 19:35:22 +053096import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053097import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053098
99/**
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530100 * Represents implementation of resolution object which will be resolved by
101 * linker.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530102 *
103 * @param <T> type of resolution entity uses / type
104 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530105public class YangResolutionInfoImpl<T>
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530106 implements YangResolutionInfo<T>, Serializable {
107
108 private static final long serialVersionUID = 806201658L;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530109
110 /**
111 * Information about the entity that needs to be resolved.
112 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530113 private YangEntityToResolveInfoImpl<T> entityToResolveInfo;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530114
115 /**
116 * Error line number.
117 */
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530118 private transient int lineNumber;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530119
120 /**
121 * Error character position in number.
122 */
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530123 private transient int charPosition;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530124
125 /**
126 * Current module/sub-module reference, will be used in inter-file/
127 * inter-jar scenario to get the import/include list.
128 */
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530129 private transient YangReferenceResolver curReferenceResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530130
131 /**
132 * Stack for type/uses is maintained for hierarchical references, this is
133 * used during resolution.
134 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530135 private Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530136
137 /**
138 * It is private to ensure the overloaded method be invoked to create an
139 * object.
140 */
141 @SuppressWarnings("unused")
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530142 private YangResolutionInfoImpl() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530143 }
144
145 /**
146 * Creates a resolution information object with all the inputs.
147 *
148 * @param dataNode current parsable data node
149 * @param holderNode parent YANG node
150 * @param lineNumber error line number
151 * @param charPositionInLine error character position in line
152 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530153 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
154 setEntityToResolveInfo(new YangEntityToResolveInfoImpl<>());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530155 getEntityToResolveInfo().setEntityToResolve(dataNode);
156 getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
157 this.setLineNumber(lineNumber);
158 this.setCharPosition(charPositionInLine);
159 setPartialResolvedStack(new Stack<>());
160 }
161
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530162 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530163 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
164 throws DataModelException {
165
166 setCurReferenceResolver(dataModelRootNode);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530167 /**
168 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
169 * YANG leafref or YANG base or YANG identityref.
170 */
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530171 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
172
173 // Check if linking is already done
174 if (entityToResolve instanceof Resolvable) {
175 Resolvable resolvable = (Resolvable) entityToResolve;
176 if (resolvable.getResolvableStatus() == RESOLVED) {
177 /**
178 * entity is already resolved, so nothing to do
179 */
180 return;
181 }
182 } else {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530183 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
Shankara-Huawei234cd092016-07-14 11:35:34 +0530184 "type/uses/if-feature/leafref/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530185 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530186 // Push the initial entity to resolve in stack.
187 addInPartialResolvedStack(getEntityToResolveInfo());
188
189 linkAndResolvePartialResolvedStack();
janani b0e4e8ae2016-07-13 21:06:41 +0530190
191 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530192 }
193
194 /**
195 * Resolves linking with ancestors.
196 *
197 * @throws DataModelException a violation of data model rules
198 */
199 private void linkAndResolvePartialResolvedStack()
200 throws DataModelException {
201
202 while (getPartialResolvedStack().size() != 0) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530203 /**
204 * Current node to resolve, it can be a YANG type or YANG uses or
205 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
206 */
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530207 T entityToResolve = getCurrentEntityToResolveFromStack();
208 // Check if linking is already done
209 if (entityToResolve instanceof Resolvable) {
210
211 Resolvable resolvable = (Resolvable) entityToResolve;
212 switch (resolvable.getResolvableStatus()) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530213 case RESOLVED: {
214 /*
215 * If the entity is already resolved in the stack, then pop
216 * it and continue with the remaining stack elements to
217 * resolve
218 */
219 getPartialResolvedStack().pop();
220 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530221 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530222
223 case LINKED: {
224 /*
225 * If the top of the stack is already linked then resolve
226 * the references and pop the entity and continue with
227 * remaining stack elements to resolve.
228 */
229 resolveTopOfStack(INTRA_FILE);
230 getPartialResolvedStack().pop();
231 break;
232 }
233
234 case INTRA_FILE_RESOLVED: {
235 /*
236 * Pop the top of the stack.
237 */
238 getPartialResolvedStack().pop();
239 break;
240 }
241
242 case UNRESOLVED: {
243 linkTopOfStackReferenceUpdateStack();
244
245 if (resolvable.getResolvableStatus() == UNRESOLVED) {
246 // If current entity is still not resolved, then
247 // linking/resolution has failed.
248 String errorInfo;
249 if (resolvable instanceof YangType) {
250 errorInfo = TYPEDEF_LINKER_ERROR;
251 } else if (resolvable instanceof YangUses) {
252 errorInfo = GROUPING_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +0530253 } else if (resolvable instanceof YangIfFeature) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530254 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530255 } else if (resolvable instanceof YangBase) {
256 errorInfo = BASE_LINKER_ERROR;
257 } else if (resolvable instanceof YangIdentityRef) {
258 errorInfo = IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +0530259 } else {
260 errorInfo = LEAFREF_LINKER_ERROR;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530261 }
262 DataModelException dataModelException =
263 new DataModelException(errorInfo);
264 dataModelException.setLine(getLineNumber());
265 dataModelException.setCharPosition(getCharPosition());
266 throw dataModelException;
267 }
268 break;
269 }
270 default: {
271 throw new DataModelException("Data Model Exception: Unsupported, linker state");
272 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530273
274 }
275
276 } else {
janani b0e4e8ae2016-07-13 21:06:41 +0530277 throw new DataModelException(
Shankara-Huawei234cd092016-07-14 11:35:34 +0530278 "Data Model Exception: Entity to resolved is other than type/uses/if-feature" +
279 "/leafref/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530280 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530281 }
282
283 }
284
285 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530286 * Adds the leafref/identityref type to the type, which has derived type referring to
287 * typedef with leafref/identityref type.
janani b0e4e8ae2016-07-13 21:06:41 +0530288 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530289 private void addDerivedRefTypeToRefTypeResolutionList()
290 throws DataModelException {
janani b0e4e8ae2016-07-13 21:06:41 +0530291
292 YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
293
294 // If holder is typedef return.
295 if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
296 return;
297 }
298
299 // If entity is not type return.
300 if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
301 return;
302 }
303
304 YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
305
306 // If type is not resolved return.
307 if (yangType.getResolvableStatus() != RESOLVED) {
308 return;
309 }
310
311 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
312
Vidyashree Ramab3670472016-08-06 15:49:56 +0530313 // If the derived types referred type is not leafref/identityref return
Shankara-Huawei234cd092016-07-14 11:35:34 +0530314 if ((derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) &&
315 (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.IDENTITYREF)) {
janani b0e4e8ae2016-07-13 21:06:41 +0530316 return;
317 }
318
319 T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
320
321 while (extendedInfo instanceof YangDerivedInfo) {
322 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
323 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
324 .getDataTypeExtendedInfo();
325 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530326
janani b0e4e8ae2016-07-13 21:06:41 +0530327 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530328 * Backup the derived types leafref/identityref info, delete all the info in current type,
329 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
330 * create a leafref/identityref resolution info using the current resolution info and
331 * add to leafref/identityref resolution list.
janani b0e4e8ae2016-07-13 21:06:41 +0530332 */
Shankara-Huawei234cd092016-07-14 11:35:34 +0530333 if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
334 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
335 yangType.resetYangType();
janani b0e4e8ae2016-07-13 21:06:41 +0530336
Shankara-Huawei234cd092016-07-14 11:35:34 +0530337 yangType.setResolvableStatus(RESOLVED);
338 yangType.setDataType(YangDataTypes.LEAFREF);
339 yangType.setDataTypeName(LEAFREF);
340 yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
341 leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
janani bebb143d2016-07-14 19:35:22 +0530342 leafRefInTypeDef.setParentNodeOfLeafref(potentialAncestorWithReferredNode);
janani b0e4e8ae2016-07-13 21:06:41 +0530343
Shankara-Huawei234cd092016-07-14 11:35:34 +0530344 // Add resolution information to the list.
345 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
janani bebb143d2016-07-14 19:35:22 +0530346 potentialAncestorWithReferredNode,
347 getLineNumber(), getCharPosition());
Shankara-Huawei234cd092016-07-14 11:35:34 +0530348 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani bebb143d2016-07-14 19:35:22 +0530349 ResolvableType.YANG_LEAFREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530350 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
351
352 } else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
353
354 YangIdentityRef identityRefInTypeDef = (YangIdentityRef) extendedInfo;
355 yangType.resetYangType();
356
357 yangType.setResolvableStatus(RESOLVED);
358 yangType.setDataType(YangDataTypes.IDENTITYREF);
359 yangType.setDataTypeName(IDENTITYREF);
360 yangType.setDataTypeExtendedInfo(identityRefInTypeDef);
361 identityRefInTypeDef.setResolvableStatus(UNRESOLVED);
362
363 // Add resolution information to the list.
364 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
janani bebb143d2016-07-14 19:35:22 +0530365 potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
Shankara-Huawei234cd092016-07-14 11:35:34 +0530366 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani bebb143d2016-07-14 19:35:22 +0530367 ResolvableType.YANG_IDENTITYREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530368 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
369 }
janani b0e4e8ae2016-07-13 21:06:41 +0530370 }
371
372 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530373 * Resolves the current entity in the stack.
374 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530375 private void resolveTopOfStack(YangLinkingPhase linkingPhase)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530376 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530377 List<T> entityToResolve = (List<T>) ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
378 if (entityToResolve != null && !entityToResolve.isEmpty()) {
379 Iterator<T> entityToResolveIterator = entityToResolve.listIterator();
380 while (entityToResolveIterator.hasNext()) {
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530381 addUnresolvedEntitiesToResolutionList(entityToResolveIterator.next());
janani bebb143d2016-07-14 19:35:22 +0530382 }
383 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530384 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
385 && ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
janani b0e4e8ae2016-07-13 21:06:41 +0530386 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530387 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
388 }
389 }
390
391 /**
janani bebb143d2016-07-14 19:35:22 +0530392 * Adds the unresolved entities to the resolution list.
393 *
394 * @param entityToResolve entity to resolve
395 * @throws DataModelException a violation of data model rules
396 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530397 private void addUnresolvedEntitiesToResolutionList(T entityToResolve)
398 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530399 if (entityToResolve instanceof YangEntityToResolveInfoImpl) {
400 YangEntityToResolveInfoImpl entityToResolveInfo = (YangEntityToResolveInfoImpl) entityToResolve;
401 if (entityToResolveInfo.getEntityToResolve() instanceof YangLeafRef) {
402 YangLeafRef leafref = (YangLeafRef) entityToResolveInfo.getEntityToResolve();
403 YangNode parentNodeOfLeafref = entityToResolveInfo.getHolderOfEntityToResolve();
404 leafref.setParentNodeOfLeafref(parentNodeOfLeafref);
405 if (leafref.getResolvableStatus() == UNRESOLVED) {
406 leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
407 }
janani bebb143d2016-07-14 19:35:22 +0530408 }
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530409
410 // Add resolution information to the list.
411 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(
412 entityToResolveInfo.getEntityToResolve(), entityToResolveInfo.getHolderOfEntityToResolve(),
413 entityToResolveInfo.getLineNumber(), entityToResolveInfo.getCharPosition());
414 addResolutionInfo(resolutionInfoImpl);
janani bebb143d2016-07-14 19:35:22 +0530415 }
416 }
417
418 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530419 * Resolves linking for a node child and siblings.
420 *
421 * @throws DataModelException data model error
422 */
423 private void linkTopOfStackReferenceUpdateStack()
424 throws DataModelException {
425
janani bebb143d2016-07-14 19:35:22 +0530426 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
427 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
428 return;
429 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530430 /*
431 * Check if self file reference is there, this will not check for the
432 * scenario when prefix is not present and type/uses is present in
433 * sub-module from include list.
434 */
435 if (!isCandidateForSelfFileReference()) {
436 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
437 return;
438 }
439
440 /**
441 * Try to resolve the top of the stack and update partial resolved stack
442 * if there is recursive references
443 */
444 YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
445 .getHolderOfEntityToResolve();
446
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530447 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
448 resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
449 return;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530450 } else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
451 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
452 resolveSelfFileLinkingForBaseAndIdentityref();
453 return;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530454 } else {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530455
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530456 YangType type = null;
457 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
458 type = (YangType) getCurrentEntityToResolveFromStack();
459 }
460
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530461 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530462 * Traverse up in the ancestor tree to check if the referred node is
463 * defined
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530464 */
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530465 while (potentialAncestorWithReferredNode != null) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530466
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530467 /**
468 * Check for the referred node defined in a ancestor scope
469 */
470 YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
471 if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
472 return;
473 }
474
475 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530476
477 if (type != null && potentialAncestorWithReferredNode != null) {
478 if (potentialAncestorWithReferredNode.getParent() == null) {
479 type.setTypeNotResolvedTillRootNode(true);
480 }
481 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530482 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530483 }
484
485 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530486 * 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 +0530487 * resolution via include list.
488 */
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530489 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530490 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
491 }
492 }
493
494 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530495 * Resolves self file linking for base/identityref.
496 *
497 * @throws DataModelException a violation of data model rules
498 */
499 private void resolveSelfFileLinkingForBaseAndIdentityref()
500 throws DataModelException {
501
502 boolean referredIdentityFound = false;
503 String nodeName = null;
504
505 if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
janani bebb143d2016-07-14 19:35:22 +0530506 nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530507 }
508
509 if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
510 nodeName = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName();
511 }
512
513 if (getCurReferenceResolver() instanceof YangModule) {
514 YangModule rootNode = (YangModule) getCurReferenceResolver();
515 // Sends list of nodes for finding the target identity.
516 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
517 } else if (getCurReferenceResolver() instanceof YangSubModule) {
518 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
519 // Sends list of nodes for finding the target identity.
520 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
521 }
522
523 if (referredIdentityFound) {
524 return;
525 }
526
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530527 /*
528 * In case prefix is not present or it's self prefix it's a candidate for inter-file
529 * resolution via include list.
530 */
531 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530532 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
533 }
534 }
535
536 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530537 * Returns the root parent with respect to the ancestor count from leafref.
538 *
539 * @param ancestorCount count of node where parent node can be reached
540 * @param currentParent current parent node
541 * @return root node
542 * @throws DataModelException a violation of data model rules
543 */
544 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
545 throws DataModelException {
546
547 int currentParentCount = 1;
548 while (currentParentCount < ancestorCount) {
549 if (currentParent.getParent() == null) {
550 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
551 }
552 currentParent = currentParent.getParent();
553 currentParentCount = currentParentCount + 1;
554 }
555 return currentParent;
556 }
557
558 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530559 * Resolves self file linking for if-feature.
560 *
561 * @param potentialAncestorWithReferredNode if-feature holder node
562 * @throws DataModelException DataModelException a violation of data model
563 * rules
564 */
565 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
566 throws DataModelException {
567
568 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
569 YangNode potentialReferredNode = (YangNode) featureHolder;
570 if (isReferredNode(potentialReferredNode)) {
571
572 // Adds reference link of entity to the node under resolution.
573 addReferredEntityLink(potentialReferredNode, LINKED);
574
575 /**
576 * resolve the reference and update the partial resolution stack
577 * with any further recursive references
578 */
579 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
580 return;
581 }
582
583 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530584 * 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 +0530585 * resolution via include list.
586 */
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530587 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530588 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
589 }
590 }
591
janani b0e4e8ae2016-07-13 21:06:41 +0530592 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530593 * Returns the status of the referred identity found for base/identityref.
594 *
janani bebb143d2016-07-14 19:35:22 +0530595 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
Shankara-Huawei234cd092016-07-14 11:35:34 +0530596 * @param ancestorWithTheReferredNode the parent node of base/identityref
597 * @return status of referred base/identityref
598 * @throws DataModelException a violation of data model rules
599 */
600 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
601 throws DataModelException {
602
603 // When child is not present return.
604 if (ancestorWithTheReferredNode.getChild() == null) {
605 return false;
606 }
607
608 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
609
610 // Checks all the siblings under the node and returns the matched node.
611 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
612
613 if (nodeFound != null) {
614 // Adds reference link of entity to the node under resolution.
615 addReferredEntityLink(nodeFound, LINKED);
616
617 /**
618 * resolve the reference and update the partial resolution stack with any further recursive references
619 */
620 addUnresolvedRecursiveReferenceToStack(nodeFound);
621 return true;
622 }
623
624 return false;
625 }
626
627 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530628 * Adds the unresolved constructs to stack which has to be resolved for leafref.
629 *
janani bebb143d2016-07-14 19:35:22 +0530630 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
janani b0e4e8ae2016-07-13 21:06:41 +0530631 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
632 */
633 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
634
635 YangType referredTypeInLeafOrLeafList;
636 if (yangleafOrLeafList instanceof YangLeaf) {
637 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
638 referredTypeInLeafOrLeafList = leaf.getDataType();
639 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
640 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
641 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
642 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
643 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
644 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
645 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
646 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
647 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
648 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
649 }
650 } else {
651 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
652 referredTypeInLeafOrLeafList = leafList.getDataType();
653 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
654 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
655 unResolvedEntityInfo
656 .setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
657 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
658 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
659 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
660 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
661 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
662 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
663 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
664 }
665 }
666 }
667
668 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530669 * Returns feature holder(module/sub-module node) .
670 *
671 * @param potentialAncestorWithReferredNode if-feature holder node
672 */
673 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
674 while (potentialAncestorWithReferredNode != null) {
675 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
676 return (YangFeatureHolder) potentialAncestorWithReferredNode;
677 }
678 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
679 }
680 return null;
681 }
682
683 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530684 * Checks if the reference in self file or in external file.
685 *
686 * @return true if self file reference, false otherwise
687 * @throws DataModelException a violation of data model rules
688 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530689 private boolean isCandidateForSelfFileReference()
690 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530691 String prefix = getRefPrefix();
692 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
693 }
694
695 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530696 * Checks for the referred parent node for the leafref path.
697 *
698 * @param potentialReferredNode potential referred node
699 * @return the reffered parent node of leaf/leaf-list
700 * @throws DataModelException data model errors
701 */
702 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
703 throws DataModelException {
704
705 while (potentialReferredNode != null) {
706 if (potentialReferredNode instanceof YangInput) {
707 if (referredNodeName.equalsIgnoreCase(INPUT)) {
708 return potentialReferredNode;
709 }
710 } else if (potentialReferredNode instanceof YangOutput) {
711 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
712 return potentialReferredNode;
713 }
714 }
715 // Check if the potential referred node is the actual referred node
716 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
717 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
718 if (potentialReferredNode.getParent() instanceof YangRpc) {
719 potentialReferredNode = potentialReferredNode.getNextSibling();
720 } else {
721 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
722 }
723 }
724 return potentialReferredNode;
725 }
726 potentialReferredNode = potentialReferredNode.getNextSibling();
727 }
728 return null;
729 }
730
731 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530732 * Checks for the referred parent node for the base/identity.
733 *
734 * @param potentialReferredNode potential referred node
735 * @return the reffered parent node of base/identity.
736 * @throws DataModelException data model errors
737 */
738 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530739 String referredNodeName)
740 throws DataModelException {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530741
742 while (potentialReferredNode != null) {
743 if (potentialReferredNode instanceof YangIdentity) {
744 // Check if the potential referred node is the actual referred node
745 if (isReferredNodeForIdentity(potentialReferredNode, referredNodeName)) {
746 return potentialReferredNode;
747 }
748 }
749 potentialReferredNode = potentialReferredNode.getNextSibling();
750 }
751 return null;
752 }
753
754 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530755 * Checks if the current reference node name and the name in the path are equal.
756 *
757 * @param currentReferredNode the node where the reference is pointed
janani bebb143d2016-07-14 19:35:22 +0530758 * @param nameOfNodeinPath name of the node in the path
janani b0e4e8ae2016-07-13 21:06:41 +0530759 * @return status of the match between the name
760 * @throws DataModelException a violation of data model rules
761 */
762 private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
763 throws DataModelException {
764
765 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
766 /*
767 * Check if name of node name matches with the current reference
768 * node.
769 */
770 return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
771 } else {
772 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
773 }
774 }
775
776 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530777 * Checks if the current reference node name and the name in the base/identityref base are equal.
778 *
janani bebb143d2016-07-14 19:35:22 +0530779 * @param currentReferredNode the node where the reference is pointed
Shankara-Huawei234cd092016-07-14 11:35:34 +0530780 * @param nameOfIdentityRefBase name of the base in the base/identityref base
781 * @return status of the match between the name
782 * @throws DataModelException a violation of data model rules
783 */
784 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
785 throws DataModelException {
786
787 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
788 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530789
790 //Check if name of node name matches with the current reference node.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530791 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
792 } else {
793 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref");
794 }
795 }
796
797 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530798 * Checks for the referred node defined in a ancestor scope.
799 *
800 * @param potentialReferredNode potential referred node
801 * @return status of resolution and updating the partial resolved stack with
802 * the any recursive references
janani b0e4e8ae2016-07-13 21:06:41 +0530803 * @throws DataModelException a violation of data model rules
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530804 */
805 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
806 throws DataModelException {
807 while (potentialReferredNode != null) {
808
809 // Check if the potential referred node is the actual referred node
810 if (isReferredNode(potentialReferredNode)) {
811
812 // Adds reference link of entity to the node under resolution.
813 addReferredEntityLink(potentialReferredNode, LINKED);
814
815 /**
816 * resolve the reference and update the partial resolution stack
817 * with any further recursive references
818 */
819 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
820
821 /*
822 * return true, since the reference is linked and any recursive
823 * unresolved references is added to the stack
824 */
825 return true;
826 }
827
828 potentialReferredNode = potentialReferredNode.getNextSibling();
829 }
830 return false;
831 }
832
833 /**
834 * Checks if the potential referred node is the actual referred node.
835 *
836 * @param potentialReferredNode typedef/grouping node
837 * @return true if node is of resolve type otherwise false
838 * @throws DataModelException a violation of data model rules
839 */
840 private boolean isReferredNode(YangNode potentialReferredNode)
841 throws DataModelException {
842 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
843 if (potentialReferredNode instanceof YangTypeDef) {
844 /*
845 * Check if name of node name matches with the entity being
846 * resolved
847 */
848 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
849 }
850 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
851 if (potentialReferredNode instanceof YangGrouping) {
852 /*
853 * Check if name of node name matches with the entity being
854 * resolved
855 */
856 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
857 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530858 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
859 if (potentialReferredNode instanceof YangFeatureHolder) {
860 /*
861 * Check if name of node name matches with the entity being
862 * resolved
863 */
864 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
865 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530866 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
867 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
868 if (potentialReferredNode instanceof YangIdentity) {
869 /*
870 * Check if name of node name matches with the entity being
871 * resolved
872 */
873 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
874 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530875 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530876 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
janani bebb143d2016-07-14 19:35:22 +0530877 "uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530878 }
879 return false;
880 }
881
882 /**
883 * Checks if node name is same as name in resolution info, i.e. name of
884 * typedef/grouping is same as name of type/uses.
885 *
886 * @param node typedef/grouping node
887 * @return true if node name is same as name in resolution info, otherwise
888 * false
889 * @throws DataModelException a violation of data model rules
890 */
891
892 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
893 throws DataModelException {
894 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
895 if (node.getName().contentEquals(
896 ((YangType<?>) getCurrentEntityToResolveFromStack())
897 .getDataTypeName())) {
898 return true;
899 }
900 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
901 if (node.getName().contentEquals(
902 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
903 return true;
904 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530905 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
906 return isFeatureDefinedInNode(node);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530907 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
908 if (node.getName().contentEquals(
909 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
910 return true;
911 }
912 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
913 if (node.getName().contentEquals(
914 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
915 return true;
916 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530917 } else {
918 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
919 }
920 return false;
921 }
922
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530923 private boolean isFeatureDefinedInNode(YangNode node)
924 throws DataModelException {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530925 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
926 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
927 if (featureList != null && !featureList.isEmpty()) {
928 Iterator<YangFeature> iterator = featureList.iterator();
929 while (iterator.hasNext()) {
930 YangFeature feature = iterator.next();
931 if (ifFeature.getName().equals(feature.getName())) {
932 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
933 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
934 return true;
935 }
936 }
937 }
938 return false;
939 }
940
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530941 /**
942 * Adds reference of grouping/typedef in uses/type.
943 *
944 * @param referredNode grouping/typedef node being referred
945 * @param linkedStatus linked status if success.
946 * @throws DataModelException a violation of data model rules
947 */
948 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
949 throws DataModelException {
950 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530951 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
952 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530953 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
954 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
955 ((YangUses) getCurrentEntityToResolveFromStack())
956 .setRefGroup((YangGrouping) referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530957 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
958 // do nothing , referred node is already set
janani b0e4e8ae2016-07-13 21:06:41 +0530959 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
960 // do nothing , referred node is already set
Shankara-Huawei234cd092016-07-14 11:35:34 +0530961 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
962 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
963 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
964 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530965 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530966 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +0530967 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530968 }
969
970 // Sets the resolution status in inside the type/uses.
971 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
972 }
973
974 /**
975 * Checks if type/grouping has further reference to typedef/ unresolved
976 * uses. Add it to the partial resolve stack and return the status of
977 * addition to stack.
978 *
979 * @param referredNode grouping/typedef node
980 * @throws DataModelException a violation of data model rules
981 */
982 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
983 throws DataModelException {
984 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530985
986 //Checks if typedef type is derived
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530987 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530988
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530989 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530990 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
991 .getTypeDefBaseType());
992 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530993 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530994 }
995
996 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
997 /*
998 * Search if the grouping has any un resolved uses child, if so
999 * return true, else return false.
1000 */
1001 addUnResolvedUsesToStack(referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301002 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1003 addUnResolvedIfFeatureToStack(referredNode);
janani b0e4e8ae2016-07-13 21:06:41 +05301004 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1005 // do nothing , referred node is already set
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301006 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
Shankara-Huawei234cd092016-07-14 11:35:34 +05301007 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1008 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301009
1010 //Search if the identity has any un resolved base, if so return true, else return false.
Shankara-Huawei234cd092016-07-14 11:35:34 +05301011 addUnResolvedBaseToStack(referredNode);
1012 } else {
1013 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
janani bebb143d2016-07-14 19:35:22 +05301014 "base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301015 }
1016 }
1017
1018 /**
1019 * Returns if there is any unresolved uses in grouping.
1020 *
1021 * @param node grouping/typedef node
1022 */
1023 private void addUnResolvedUsesToStack(YangNode node) {
1024
Vidyashree Ramab3670472016-08-06 15:49:56 +05301025 //Search the grouping node's children for presence of uses node.
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301026 TraversalType curTraversal = ROOT;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301027 YangNode curNode = node.getChild();
1028 while (curNode != null) {
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301029 if (curNode.getName().equals(node.getName())) {
1030 // if we have traversed all the child nodes, then exit from loop
1031 return;
1032 }
1033
1034 // if child nodes has uses, then add it to resolution stack
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301035 if (curNode instanceof YangUses) {
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301036 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301037 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1038 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301039 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301040 }
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301041
1042 // Traversing all the child nodes of grouping
1043 if (curTraversal != PARENT && curNode.getChild() != null) {
1044 curTraversal = CHILD;
1045 curNode = curNode.getChild();
1046 } else if (curNode.getNextSibling() != null) {
1047 curTraversal = SIBILING;
1048 curNode = curNode.getNextSibling();
1049 } else {
1050 curTraversal = PARENT;
1051 curNode = curNode.getParent();
1052 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301053 }
1054 }
1055
1056 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301057 * Returns if there is any unresolved if-feature in feature.
1058 *
1059 * @param node module/submodule node
1060 */
1061 private void addUnResolvedIfFeatureToStack(YangNode node) {
1062 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1063 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1064 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1065 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1066 while (ifFeatureIterator.hasNext()) {
1067 YangIfFeature ifFeature = ifFeatureIterator.next();
1068 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1069 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1070 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1071 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1072 }
1073 }
1074 }
1075
1076 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +05301077 * Returns if there is any unresolved base in identity.
1078 *
1079 * @param node module/submodule node
1080 */
1081 private void addUnResolvedBaseToStack(YangNode node) {
1082
1083 YangIdentity curNode = (YangIdentity) node;
1084 if (curNode.getBaseNode() != null) {
1085 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1086 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1087 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1088 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1089 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1090
1091 }
1092 }
1093 }
1094
1095
1096 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301097 * Returns stack of YANG type with partially resolved YANG construct
1098 * hierarchy.
1099 *
1100 * @return partial resolved YANG construct stack
1101 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301102 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301103 return partialResolvedStack;
1104 }
1105
1106 /**
1107 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1108 *
1109 * @param partialResolvedStack partial resolved YANG construct stack
1110 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301111 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301112 this.partialResolvedStack = partialResolvedStack;
1113 }
1114
1115 /**
1116 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1117 *
1118 * @param partialResolvedInfo partial resolved YANG construct stack
1119 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301120 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301121 getPartialResolvedStack().push(partialResolvedInfo);
1122 }
1123
1124 /**
1125 * Retrieves the next entity in the stack that needs to be resolved. It is
1126 * assumed that the caller ensures that the stack is not empty.
1127 *
1128 * @return next entity in the stack that needs to be resolved
1129 */
1130 private T getCurrentEntityToResolveFromStack() {
1131 return getPartialResolvedStack().peek().getEntityToResolve();
1132 }
1133
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301134 @Override
1135 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301136 return entityToResolveInfo;
1137 }
1138
1139 /**
1140 * Sets information about the entity that needs to be resolved.
1141 *
1142 * @param entityToResolveInfo information about the entity that needs to be
1143 * resolved
1144 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301145 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301146 this.entityToResolveInfo = entityToResolveInfo;
1147 }
1148
1149 @Override
1150 public int getLineNumber() {
1151 return lineNumber;
1152 }
1153
1154 @Override
1155 public int getCharPosition() {
1156 return charPosition;
1157 }
1158
1159 @Override
1160 public void setLineNumber(int lineNumber) {
1161 this.lineNumber = lineNumber;
1162 }
1163
1164 @Override
1165 public void setCharPosition(int charPositionInLine) {
1166 this.charPosition = charPositionInLine;
1167 }
1168
1169 /**
1170 * Returns current module/sub-module reference, will be used in inter-file/
1171 * inter-jar scenario to get the import/include list.
1172 *
1173 * @return current module/sub-module reference
1174 */
1175 private YangReferenceResolver getCurReferenceResolver() {
1176 return curReferenceResolver;
1177 }
1178
1179 /**
1180 * Sets current module/sub-module reference, will be used in inter-file/
1181 * inter-jar scenario to get the import/include list.
1182 *
1183 * @param curReferenceResolver current module/sub-module reference
1184 */
1185 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1186 this.curReferenceResolver = curReferenceResolver;
1187 }
1188
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301189 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301190 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1191 throws DataModelException {
1192
1193 setCurReferenceResolver(dataModelRootNode);
1194
1195 // Current node to resolve, it can be a YANG type or YANG uses.
1196 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1197
1198 // Check if linking is already done
1199 if (entityToResolve instanceof Resolvable) {
1200 Resolvable resolvable = (Resolvable) entityToResolve;
1201 if (resolvable.getResolvableStatus() == RESOLVED) {
1202 return;
1203 }
1204 } else {
1205 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1206 }
1207
janani bebb143d2016-07-14 19:35:22 +05301208 if (entityToResolve instanceof YangXPathResolver && !(entityToResolve instanceof YangLeafRef)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +05301209 //Process x-path linking.
janani bebb143d2016-07-14 19:35:22 +05301210 processXPathLinking(entityToResolve, dataModelRootNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301211
Bharat saraswald14cbe82016-07-14 13:26:18 +05301212 } else {
janani b0e4e8ae2016-07-13 21:06:41 +05301213
Bharat saraswald14cbe82016-07-14 13:26:18 +05301214 // Push the initial entity to resolve in stack.
1215 addInPartialResolvedStack(getEntityToResolveInfo());
1216
1217 // Inter file linking and resolution.
1218 linkInterFileAndResolve();
1219
1220 addDerivedRefTypeToRefTypeResolutionList();
1221 }
1222 }
1223
1224 /**
1225 * Process x-path linking for augment and leaf-ref.
1226 *
janani bebb143d2016-07-14 19:35:22 +05301227 * @param entityToResolve entity to resolve
1228 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +05301229 */
janani bebb143d2016-07-14 19:35:22 +05301230 private void processXPathLinking(T entityToResolve,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301231 YangReferenceResolver root) {
janani bebb143d2016-07-14 19:35:22 +05301232
Bharat saraswald14cbe82016-07-14 13:26:18 +05301233 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
janani bebb143d2016-07-14 19:35:22 +05301234
Bharat saraswald14cbe82016-07-14 13:26:18 +05301235 if (entityToResolve instanceof YangAugment) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301236 YangNode targetNode = null;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301237 YangAugment augment = (YangAugment) entityToResolve;
1238 targetNode = xPathLinker.processAugmentXpathLinking(augment.getTargetNode(),
1239 (YangNode) root);
1240 if (targetNode != null) {
1241 if (targetNode instanceof YangAugmentableNode) {
1242 detectCollisionForAugmentedNode(targetNode, augment);
1243 ((YangAugmentableNode) targetNode).addAugmentation(augment);
Vidyashree Rama052ada62016-08-17 14:03:29 +05301244 ((YangAugmentableNode) targetNode).setIsAugmented(true);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301245 augment.setAugmentedNode(targetNode);
1246 Resolvable resolvable = (Resolvable) entityToResolve;
1247 resolvable.setResolvableStatus(RESOLVED);
1248 } else {
1249 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for "
1250 + augment.getName());
1251 }
1252 } else {
1253 throw new LinkerException("Failed to link " + augment.getName());
1254 }
Vidyashree Ramab3670472016-08-06 15:49:56 +05301255 } else if (entityToResolve instanceof YangCompilerAnnotation) {
1256 YangNode targetNode;
1257 YangCompilerAnnotation ca = (YangCompilerAnnotation) entityToResolve;
1258
1259 targetNode = xPathLinker.processAugmentXpathLinking(ca.getAtomicPathList(),
1260 (YangNode) root);
1261 if (targetNode != null) {
1262 if (targetNode instanceof YangList) {
1263 ((YangList) targetNode).setCompilerAnnotation(
1264 (YangCompilerAnnotation) entityToResolve);
1265 Resolvable resolvable = (Resolvable) entityToResolve;
1266 resolvable.setResolvableStatus(RESOLVED);
1267 } else {
1268 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for compiler" +
1269 " annotation " + ca.getPath());
1270 }
1271 } else {
1272 throw new LinkerException("Failed to link compiler annotation " + ca.getPath());
1273 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301274 } else if (entityToResolve instanceof YangLeafRef) {
1275 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
1276 Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
janani bebb143d2016-07-14 19:35:22 +05301277 (YangNode) root, leafRef);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301278 if (target != null) {
1279 YangLeaf leaf = null;
1280 YangLeafList leafList = null;
1281 leafRef.setReferredLeafOrLeafList(target);
1282 if (target instanceof YangLeaf) {
1283 leaf = (YangLeaf) target;
janani bebb143d2016-07-14 19:35:22 +05301284 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1285 addUnResolvedLeafRefTypeToStack((T) leaf, getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301286 } else {
1287 leafList = (YangLeafList) target;
janani bebb143d2016-07-14 19:35:22 +05301288 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1289 addUnResolvedLeafRefTypeToStack((T) leafList,
1290 getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301291 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301292 //TODO: add logic for leaf-ref for path predicates.
1293 } else {
janani bebb143d2016-07-14 19:35:22 +05301294 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
1295 "leaf/leaf-list for given leafref path "
Bharat saraswald14cbe82016-07-14 13:26:18 +05301296 + leafRef.getPath());
janani bebb143d2016-07-14 19:35:22 +05301297 linkerException.setCharPosition(leafRef.getCharPosition());
1298 linkerException.setLine(leafRef.getLineNumber());
1299 throw linkerException;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301300 }
1301 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301302 }
1303
1304 /**
1305 * Returns the referenced prefix of entity under resolution.
1306 *
1307 * @return referenced prefix of entity under resolution
1308 * @throws DataModelException a violation in data model rule
1309 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301310 private String getRefPrefix()
1311 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301312 String refPrefix;
1313 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1314 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1315 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1316 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301317 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1318 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301319 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1320 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1321 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1322 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301323 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301324 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
janani bebb143d2016-07-14 19:35:22 +05301325 "type/uses/base/identityref");
janani b0e4e8ae2016-07-13 21:06:41 +05301326 }
1327 return refPrefix;
1328 }
1329
1330 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301331 * Performs inter file linking and resolution.
1332 *
1333 * @throws DataModelException a violation in data model rule
1334 */
1335 private void linkInterFileAndResolve()
1336 throws DataModelException {
1337
1338 while (getPartialResolvedStack().size() != 0) {
1339
1340 // Current node to resolve, it can be a YANG type or YANG uses.
1341 T entityToResolve = getCurrentEntityToResolveFromStack();
1342 // Check if linking is already done
1343 if (entityToResolve instanceof Resolvable) {
1344
1345 Resolvable resolvable = (Resolvable) entityToResolve;
1346 switch (resolvable.getResolvableStatus()) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301347 case RESOLVED: {
1348 /*
1349 * If the entity is already resolved in the stack, then pop
1350 * it and continue with the remaining stack elements to
1351 * resolve
1352 */
1353 getPartialResolvedStack().pop();
1354 break;
1355 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301356
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301357 case INTER_FILE_LINKED: {
1358 /*
1359 * If the top of the stack is already linked then resolve
1360 * the references and pop the entity and continue with
1361 * remaining stack elements to resolve
1362 */
1363 resolveTopOfStack(INTER_FILE);
1364 getPartialResolvedStack().pop();
1365 break;
1366 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301367
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301368 case INTRA_FILE_RESOLVED: {
1369 /*
1370 * If the top of the stack is intra file resolved then check
1371 * if top of stack is linked, if not link it using
1372 * import/include list and push the linked referred entity
1373 * to the stack, otherwise only push it to the stack.
1374 */
1375 linkInterFileTopOfStackRefUpdateStack();
1376 break;
1377 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301378
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301379 case UNDEFINED: {
1380 /*
1381 * In case of if-feature resolution, if referred "feature" is not
1382 * defined then the resolvable status will be undefined.
1383 */
1384 getPartialResolvedStack().pop();
1385 break;
1386 }
1387
1388 default: {
1389 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1390 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301391
1392 }
1393
1394 } else {
1395 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1396 }
1397
1398 }
1399
1400 }
1401
1402 /**
1403 * Links the top of the stack if it's inter-file and update stack.
1404 *
1405 * @throws DataModelException data model error
1406 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301407 private void linkInterFileTopOfStackRefUpdateStack()
1408 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301409
janani bebb143d2016-07-14 19:35:22 +05301410 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1411 // When leafref path comes with relative path, it will be converted to absolute path.
1412 setAbsolutePathFromRelativePathInLeafref(getCurrentEntityToResolveFromStack());
1413 processXPathLinking(getCurrentEntityToResolveFromStack(), getCurReferenceResolver());
1414 return;
1415 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301416 /*
1417 * Obtain the referred node of top of stack entity under resolution
1418 */
1419 T referredNode = getRefNode();
1420
1421 /*
1422 * Check for null for scenario when it's not linked and inter-file
1423 * linking is required.
1424 */
1425 if (referredNode == null) {
1426
1427 /*
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301428 * Check if prefix is null or not, to identify whether to search in
1429 * import list or include list.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301430 */
Bharat saraswal5cd9e9c2016-05-26 23:48:38 +05301431 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301432 if (resolveWithImport()) {
1433 return;
1434 }
1435 } else {
1436 if (resolveWithInclude()) {
1437 return;
1438 }
1439 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301440
1441 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1442 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1443 return;
1444 }
janani b0e4e8ae2016-07-13 21:06:41 +05301445 // If current entity is still not resolved, then
1446 // linking/resolution has failed.
1447 String errorInfo;
1448 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1449 errorInfo = TYPEDEF_LINKER_ERROR;
1450 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1451 errorInfo = GROUPING_LINKER_ERROR;
1452 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1453 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huawei234cd092016-07-14 11:35:34 +05301454 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1455 errorInfo = BASE_LINKER_ERROR;
1456 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1457 errorInfo = IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +05301458 } else {
1459 errorInfo = LEAFREF_LINKER_ERROR;
1460 }
1461 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301462 dataModelException.setLine(getLineNumber());
1463 dataModelException.setCharPosition(getCharPosition());
1464 throw dataModelException;
1465 } else {
janani bebb143d2016-07-14 19:35:22 +05301466 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1467 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1468 }
1469 }
1470
1471 /**
1472 * Sets the leafref with absolute path from the relative path.
1473 *
1474 * @param resolutionInfo information about the YANG construct which has to be resolved
1475 * @throws DataModelException a violation of data model rules
1476 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301477 public void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo)
1478 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301479 if (resolutionInfo instanceof YangLeafRef) {
1480
1481 YangNode parentOfLeafref = ((YangLeafRef) resolutionInfo).getParentNodeOfLeafref();
1482 YangLeafRef leafref = (YangLeafRef) resolutionInfo;
1483
1484 // Checks if the leafref has relative path in it.
1485 if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
1486 YangRelativePath relativePath = leafref.getRelativePath();
1487 List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
1488 int numberOfAncestors = relativePath.getAncestorNodeCount();
1489
1490 // Gets the root node from the ancestor count.
1491 T nodeOrAugmentList = getRootNodeWithAncestorCountForLeafref(numberOfAncestors, parentOfLeafref,
1492 leafref);
1493 if (nodeOrAugmentList instanceof YangNode) {
1494 String pathNameToBePrefixed = EMPTY_STRING;
1495 YangNode rootNode = (YangNode) nodeOrAugmentList;
1496 // Forms a new absolute path from the relative path
1497 while (!(rootNode instanceof YangReferenceResolver)) {
1498 pathNameToBePrefixed = rootNode.getName() + SLASH_FOR_STRING + pathNameToBePrefixed;
1499 rootNode = rootNode.getParent();
1500 if (rootNode == null) {
1501 throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
1502 }
1503 }
1504 fillAbsolutePathValuesInLeafref(leafref, pathNameToBePrefixed, absoluteInRelative);
1505 } else {
1506 List<String> listOfAugment = (List<String>) nodeOrAugmentList;
1507 Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
1508 String augment = EMPTY_STRING;
1509 while (listOfAugmentIterator.hasNext()) {
1510 augment = augment + SLASH_FOR_STRING + listOfAugmentIterator.next();
1511 }
1512 fillAbsolutePathValuesInLeafref(leafref, augment, absoluteInRelative);
janani b0e4e8ae2016-07-13 21:06:41 +05301513 }
janani b0e4e8ae2016-07-13 21:06:41 +05301514 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301515 }
1516 }
1517
1518 /**
janani bebb143d2016-07-14 19:35:22 +05301519 * Fills the absolute path values in the leafref from relative path.
1520 *
Bharat saraswal8beac342016-08-04 02:00:03 +05301521 * @param leafref instance of YANG leafref
1522 * @param pathNameToBePrefixed path name which has to be prefixed to relative path
1523 * @param atomicPathsInRelative atomic paths in relative
janani bebb143d2016-07-14 19:35:22 +05301524 * @throws DataModelException a violation of data model rules
1525 */
1526 private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String pathNameToBePrefixed,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301527 List<YangAtomicPath> atomicPathsInRelative)
1528 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301529
1530 leafref.setPathType(YangPathArgType.ABSOLUTE_PATH);
1531 String[] pathName = new String[0];
1532 if (pathNameToBePrefixed != EMPTY_STRING && pathNameToBePrefixed != null) {
1533 pathName = pathNameToBePrefixed.split(SLASH_FOR_STRING);
1534 }
1535 List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
1536 for (String value : pathName) {
1537 if (value != null && !value.isEmpty() && value != EMPTY_STRING) {
1538 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(value, YangConstructType.PATH_DATA);
1539 YangAtomicPath atomicPath = new YangAtomicPath();
1540 atomicPath.setNodeIdentifier(nodeIdentifier);
1541 finalListForAbsolute.add(atomicPath);
1542 }
1543 }
1544 if (atomicPathsInRelative != null && !atomicPathsInRelative.isEmpty()) {
1545 Iterator<YangAtomicPath> atomicPathIterator = atomicPathsInRelative.listIterator();
1546 while (atomicPathIterator.hasNext()) {
1547 YangAtomicPath yangAtomicPath = atomicPathIterator.next();
1548 finalListForAbsolute.add(yangAtomicPath);
1549 }
1550 leafref.setAtomicPath(finalListForAbsolute);
1551 } else {
1552 DataModelException dataModelException = new DataModelException("YANG file error: The target node, in the " +
1553 "leafref path " + leafref.getPath() + ", is invalid.");
1554 dataModelException.setCharPosition(leafref.getCharPosition());
1555 dataModelException.setLine(leafref.getLineNumber());
1556 throw dataModelException;
1557 }
1558 }
1559
1560 /**
1561 * Returns the root parent with respect to the ancestor count from leafref.
1562 *
1563 * @param ancestorCount count of node where parent node can be reached
1564 * @param currentParent current parent node
1565 * @param leafref instance of YANG leafref
1566 * @return node where the ancestor count stops or augment path name list
1567 * @throws DataModelException a violation of data model rules
1568 */
1569 private T getRootNodeWithAncestorCountForLeafref(int ancestorCount, YangNode currentParent, YangLeafRef leafref)
1570 throws DataModelException {
1571
1572 int currentParentCount = 1;
1573 currentParent = skipInvalidDataNodes(currentParent, leafref);
1574 if (currentParent instanceof YangAugment) {
1575 YangAugment augment = (YangAugment) currentParent;
1576 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1577 return (T) valueInAugment;
1578 } else {
1579 while (currentParentCount < ancestorCount) {
1580 YangNode currentSkippedParent = skipInvalidDataNodes(currentParent, leafref);
1581 if (currentSkippedParent == currentParent) {
1582 if (currentParent.getParent() == null) {
1583 throw new DataModelException("YANG file error: The target node, in the leafref path "
1584 + leafref.getPath() + ", is invalid.");
1585 }
1586 currentParent = currentParent.getParent();
1587 } else {
1588 currentParent = currentSkippedParent;
1589 continue;
1590 }
1591 currentParentCount = currentParentCount + 1;
1592 if (currentParent instanceof YangAugment) {
1593 YangAugment augment = (YangAugment) currentParent;
1594 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1595 return (T) valueInAugment;
1596 }
1597 }
1598 }
1599 return (T) currentParent;
1600 }
1601
1602 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301603 * Finds and resolves with include list.
1604 *
1605 * @return true if resolved, false otherwise
1606 * @throws DataModelException a violation in data model rule
1607 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301608 private boolean resolveWithInclude()
1609 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301610 /*
1611 * Run through all the nodes in include list and search for referred
1612 * typedef/grouping at the root level.
1613 */
1614 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1615 YangNode linkedNode = null;
1616 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1617 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1618 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1619 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301620 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1621 linkedNode = findRefFeature(yangInclude.getIncludedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301622 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1623 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1624 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1625 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301626 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301627
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301628 if (linkedNode != null) {
1629 // Add the link to external entity.
1630 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301631
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301632 // Add the type/uses of referred typedef/grouping to the stack.
1633 addUnresolvedRecursiveReferenceToStack(linkedNode);
1634 return true;
1635 }
1636 }
1637 // If referred node can't be found return false.
1638 return false;
1639 }
1640
1641 /**
1642 * Finds and resolves with import list.
1643 *
1644 * @return true if resolved, false otherwise
1645 * @throws DataModelException a violation in data model rule
1646 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301647 private boolean resolveWithImport()
1648 throws DataModelException {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301649
1650 // Run through import list to find the referred typedef/grouping.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301651 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1652 /*
1653 * Match the prefix attached to entity under resolution with the
1654 * imported/included module/sub-module's prefix. If found, search
1655 * for the referred typedef/grouping at the root level.
1656 */
1657 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1658 YangNode linkedNode = null;
1659 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1660 linkedNode = findRefTypedef(yangImport.getImportedNode());
1661 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1662 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301663 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1664 linkedNode = findRefFeature(yangImport.getImportedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301665 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1666 linkedNode = findRefIdentity(yangImport.getImportedNode());
1667 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1668 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301669 }
1670 if (linkedNode != null) {
1671 // Add the link to external entity.
1672 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301673
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301674 // Add the type/uses of referred typedef/grouping to the
1675 // stack.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301676 addUnresolvedRecursiveReferenceToStack(linkedNode);
1677 return true;
1678 }
1679 /*
1680 * If referred node can't be found at root level break for loop,
1681 * and return false.
1682 */
1683 break;
1684 }
1685 }
1686 // If referred node can't be found return false.
1687 return false;
1688 }
1689
1690 /**
1691 * Returns referred typedef/grouping node.
1692 *
1693 * @return referred typedef/grouping node
1694 * @throws DataModelException a violation in data model rule
1695 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301696 private T getRefNode()
1697 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301698 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301699 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1700 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301701 return (T) derivedInfo.getReferredTypeDef();
1702 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1703 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301704 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1705 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani b0e4e8ae2016-07-13 21:06:41 +05301706 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1707 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301708 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1709 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1710 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1711 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301712 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301713 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +05301714 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301715 }
1716 }
1717
1718 /**
1719 * Finds the referred grouping node at the root level of imported/included node.
1720 *
1721 * @param refNode module/sub-module node
1722 * @return referred grouping
1723 */
1724 private YangNode findRefGrouping(YangNode refNode) {
1725 YangNode tmpNode = refNode.getChild();
1726 while (tmpNode != null) {
1727 if (tmpNode instanceof YangGrouping) {
1728 if (tmpNode.getName()
1729 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1730 return tmpNode;
1731 }
1732 }
1733 tmpNode = tmpNode.getNextSibling();
1734 }
1735 return null;
1736 }
1737
1738 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301739 * Finds the referred feature node at the root level of imported/included node.
1740 *
1741 * @param refNode module/sub-module node
1742 * @return referred feature
1743 */
1744 private YangNode findRefFeature(YangNode refNode) {
1745 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1746 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1747
1748 if (featureList != null && !featureList.isEmpty()) {
1749 Iterator<YangFeature> iterator = featureList.iterator();
1750 while (iterator.hasNext()) {
1751 YangFeature feature = iterator.next();
1752 if (ifFeature.getName().equals(feature.getName())) {
1753 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1754 return refNode;
1755 }
1756 }
1757 }
1758 return null;
1759 }
1760
1761 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301762 * Finds the referred typedef node at the root level of imported/included node.
1763 *
1764 * @param refNode module/sub-module node
1765 * @return referred typedef
1766 */
1767 private YangNode findRefTypedef(YangNode refNode) {
1768 YangNode tmpNode = refNode.getChild();
1769 while (tmpNode != null) {
1770 if (tmpNode instanceof YangTypeDef) {
1771 if (tmpNode.getName()
1772 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1773 return tmpNode;
1774 }
1775 }
1776 tmpNode = tmpNode.getNextSibling();
1777 }
1778 return null;
1779 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301780
1781 /**
1782 * Finds the referred identity node at the root level of imported/included node.
1783 *
1784 * @param refNode module/sub-module node
1785 * @return referred identity
1786 */
1787 private YangNode findRefIdentity(YangNode refNode) {
1788 YangNode tmpNode = refNode.getChild();
1789 while (tmpNode != null) {
1790 if (tmpNode instanceof YangIdentity) {
1791 if (tmpNode.getName()
1792 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1793 return tmpNode;
1794 }
1795 }
1796 tmpNode = tmpNode.getNextSibling();
1797 }
1798 return null;
1799 }
1800
1801 /**
1802 * Finds the referred identity node at the root level of imported/included node.
1803 *
1804 * @param refNode module/sub-module node
1805 * @return referred identity
1806 */
1807 private YangNode findRefIdentityRef(YangNode refNode) {
1808 YangNode tmpNode = refNode.getChild();
1809 while (tmpNode != null) {
1810 if (tmpNode instanceof YangIdentity) {
1811 if (tmpNode.getName()
1812 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
janani bebb143d2016-07-14 19:35:22 +05301813 .getBaseIdentity().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301814 return tmpNode;
1815 }
1816 }
1817 tmpNode = tmpNode.getNextSibling();
1818 }
1819 return null;
1820 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301821}