blob: 7df0de2d32b44426ddc5d1075dc347a1e47730a4 [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 */
289 private void addDerivedRefTypeToRefTypeResolutionList() throws DataModelException {
290
291 YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
292
293 // If holder is typedef return.
294 if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
295 return;
296 }
297
298 // If entity is not type return.
299 if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
300 return;
301 }
302
303 YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
304
305 // If type is not resolved return.
306 if (yangType.getResolvableStatus() != RESOLVED) {
307 return;
308 }
309
310 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
311
Vidyashree Ramab3670472016-08-06 15:49:56 +0530312 // If the derived types referred type is not leafref/identityref return
Shankara-Huawei234cd092016-07-14 11:35:34 +0530313 if ((derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) &&
314 (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.IDENTITYREF)) {
janani b0e4e8ae2016-07-13 21:06:41 +0530315 return;
316 }
317
318 T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
319
320 while (extendedInfo instanceof YangDerivedInfo) {
321 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
322 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
323 .getDataTypeExtendedInfo();
324 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530325
janani b0e4e8ae2016-07-13 21:06:41 +0530326 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530327 * Backup the derived types leafref/identityref info, delete all the info in current type,
328 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
329 * create a leafref/identityref resolution info using the current resolution info and
330 * add to leafref/identityref resolution list.
janani b0e4e8ae2016-07-13 21:06:41 +0530331 */
Shankara-Huawei234cd092016-07-14 11:35:34 +0530332 if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
333 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
334 yangType.resetYangType();
janani b0e4e8ae2016-07-13 21:06:41 +0530335
Shankara-Huawei234cd092016-07-14 11:35:34 +0530336 yangType.setResolvableStatus(RESOLVED);
337 yangType.setDataType(YangDataTypes.LEAFREF);
338 yangType.setDataTypeName(LEAFREF);
339 yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
340 leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
janani bebb143d2016-07-14 19:35:22 +0530341 leafRefInTypeDef.setParentNodeOfLeafref(potentialAncestorWithReferredNode);
janani b0e4e8ae2016-07-13 21:06:41 +0530342
Shankara-Huawei234cd092016-07-14 11:35:34 +0530343 // Add resolution information to the list.
344 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
janani bebb143d2016-07-14 19:35:22 +0530345 potentialAncestorWithReferredNode,
346 getLineNumber(), getCharPosition());
Shankara-Huawei234cd092016-07-14 11:35:34 +0530347 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani bebb143d2016-07-14 19:35:22 +0530348 ResolvableType.YANG_LEAFREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530349 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
350
351 } else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
352
353 YangIdentityRef identityRefInTypeDef = (YangIdentityRef) extendedInfo;
354 yangType.resetYangType();
355
356 yangType.setResolvableStatus(RESOLVED);
357 yangType.setDataType(YangDataTypes.IDENTITYREF);
358 yangType.setDataTypeName(IDENTITYREF);
359 yangType.setDataTypeExtendedInfo(identityRefInTypeDef);
360 identityRefInTypeDef.setResolvableStatus(UNRESOLVED);
361
362 // Add resolution information to the list.
363 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
janani bebb143d2016-07-14 19:35:22 +0530364 potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
Shankara-Huawei234cd092016-07-14 11:35:34 +0530365 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani bebb143d2016-07-14 19:35:22 +0530366 ResolvableType.YANG_IDENTITYREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530367 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
368 }
janani b0e4e8ae2016-07-13 21:06:41 +0530369 }
370
371 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530372 * Resolves the current entity in the stack.
373 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530374 private void resolveTopOfStack(YangLinkingPhase linkingPhase)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530375 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530376 List<T> entityToResolve = (List<T>) ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
377 if (entityToResolve != null && !entityToResolve.isEmpty()) {
378 Iterator<T> entityToResolveIterator = entityToResolve.listIterator();
379 while (entityToResolveIterator.hasNext()) {
380 addUnresolvedEntitiesToStack(entityToResolveIterator.next());
381 }
382 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530383 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
384 && ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
janani b0e4e8ae2016-07-13 21:06:41 +0530385 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530386 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
387 }
388 }
389
390 /**
janani bebb143d2016-07-14 19:35:22 +0530391 * Adds the unresolved entities to the resolution list.
392 *
393 * @param entityToResolve entity to resolve
394 * @throws DataModelException a violation of data model rules
395 */
396 private void addUnresolvedEntitiesToStack(T entityToResolve) throws DataModelException {
397 if (entityToResolve instanceof YangEntityToResolveInfoImpl) {
398 YangEntityToResolveInfoImpl entityToResolveInfo = (YangEntityToResolveInfoImpl) entityToResolve;
399 if (entityToResolveInfo.getEntityToResolve() instanceof YangLeafRef) {
400 YangLeafRef leafref = (YangLeafRef) entityToResolveInfo.getEntityToResolve();
401 YangNode parentNodeOfLeafref = entityToResolveInfo.getHolderOfEntityToResolve();
402 leafref.setParentNodeOfLeafref(parentNodeOfLeafref);
403 if (leafref.getResolvableStatus() == UNRESOLVED) {
404 leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
405 }
406 // Add resolution information to the list.
407 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafref,
408 parentNodeOfLeafref, entityToResolveInfo.getLineNumber(),
409 entityToResolveInfo.getCharPosition());
410 addResolutionInfo(resolutionInfoImpl);
411 }
412 }
413 }
414
415 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530416 * Resolves linking for a node child and siblings.
417 *
418 * @throws DataModelException data model error
419 */
420 private void linkTopOfStackReferenceUpdateStack()
421 throws DataModelException {
422
janani bebb143d2016-07-14 19:35:22 +0530423 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
424 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
425 return;
426 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530427 /*
428 * Check if self file reference is there, this will not check for the
429 * scenario when prefix is not present and type/uses is present in
430 * sub-module from include list.
431 */
432 if (!isCandidateForSelfFileReference()) {
433 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
434 return;
435 }
436
437 /**
438 * Try to resolve the top of the stack and update partial resolved stack
439 * if there is recursive references
440 */
441 YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
442 .getHolderOfEntityToResolve();
443
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530444 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
445 resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
446 return;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530447 } else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
448 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
449 resolveSelfFileLinkingForBaseAndIdentityref();
450 return;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530451 } else {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530452
453 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530454 * Traverse up in the ancestor tree to check if the referred node is
455 * defined
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530456 */
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530457 while (potentialAncestorWithReferredNode != null) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530458
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530459 /**
460 * Check for the referred node defined in a ancestor scope
461 */
462 YangNode potentialReferredNode = potentialAncestorWithReferredNode.getChild();
463 if (isReferredNodeInSiblingListProcessed(potentialReferredNode)) {
464 return;
465 }
466
467 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
468 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530469 }
470
471 /*
472 * In case prefix is not present it's a candidate for inter-file
473 * resolution via include list.
474 */
475 if (getRefPrefix() == null) {
476 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
477 }
478 }
479
480 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530481 * Resolves self file linking for base/identityref.
482 *
483 * @throws DataModelException a violation of data model rules
484 */
485 private void resolveSelfFileLinkingForBaseAndIdentityref()
486 throws DataModelException {
487
488 boolean referredIdentityFound = false;
489 String nodeName = null;
490
491 if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
janani bebb143d2016-07-14 19:35:22 +0530492 nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530493 }
494
495 if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
496 nodeName = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName();
497 }
498
499 if (getCurReferenceResolver() instanceof YangModule) {
500 YangModule rootNode = (YangModule) getCurReferenceResolver();
501 // Sends list of nodes for finding the target identity.
502 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
503 } else if (getCurReferenceResolver() instanceof YangSubModule) {
504 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
505 // Sends list of nodes for finding the target identity.
506 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
507 }
508
509 if (referredIdentityFound) {
510 return;
511 }
512
Vidyashree Ramab3670472016-08-06 15:49:56 +0530513 //In case prefix is not present it's a candidate for inter-file resolution via include list.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530514 if (getRefPrefix() == null) {
515 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
516 }
517 }
518
519 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530520 * Returns the root parent with respect to the ancestor count from leafref.
521 *
522 * @param ancestorCount count of node where parent node can be reached
523 * @param currentParent current parent node
524 * @return root node
525 * @throws DataModelException a violation of data model rules
526 */
527 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
528 throws DataModelException {
529
530 int currentParentCount = 1;
531 while (currentParentCount < ancestorCount) {
532 if (currentParent.getParent() == null) {
533 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
534 }
535 currentParent = currentParent.getParent();
536 currentParentCount = currentParentCount + 1;
537 }
538 return currentParent;
539 }
540
541 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530542 * Resolves self file linking for if-feature.
543 *
544 * @param potentialAncestorWithReferredNode if-feature holder node
545 * @throws DataModelException DataModelException a violation of data model
546 * rules
547 */
548 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
549 throws DataModelException {
550
551 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
552 YangNode potentialReferredNode = (YangNode) featureHolder;
553 if (isReferredNode(potentialReferredNode)) {
554
555 // Adds reference link of entity to the node under resolution.
556 addReferredEntityLink(potentialReferredNode, LINKED);
557
558 /**
559 * resolve the reference and update the partial resolution stack
560 * with any further recursive references
561 */
562 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
563 return;
564 }
565
566 /*
567 * In case prefix is not present it's a candidate for inter-file
568 * resolution via include list.
569 */
570 if (getRefPrefix() == null) {
571 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
572 }
573 }
574
janani b0e4e8ae2016-07-13 21:06:41 +0530575 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530576 * Returns the status of the referred identity found for base/identityref.
577 *
janani bebb143d2016-07-14 19:35:22 +0530578 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
Shankara-Huawei234cd092016-07-14 11:35:34 +0530579 * @param ancestorWithTheReferredNode the parent node of base/identityref
580 * @return status of referred base/identityref
581 * @throws DataModelException a violation of data model rules
582 */
583 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
584 throws DataModelException {
585
586 // When child is not present return.
587 if (ancestorWithTheReferredNode.getChild() == null) {
588 return false;
589 }
590
591 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
592
593 // Checks all the siblings under the node and returns the matched node.
594 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
595
596 if (nodeFound != null) {
597 // Adds reference link of entity to the node under resolution.
598 addReferredEntityLink(nodeFound, LINKED);
599
600 /**
601 * resolve the reference and update the partial resolution stack with any further recursive references
602 */
603 addUnresolvedRecursiveReferenceToStack(nodeFound);
604 return true;
605 }
606
607 return false;
608 }
609
610 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530611 * Adds the unresolved constructs to stack which has to be resolved for leafref.
612 *
janani bebb143d2016-07-14 19:35:22 +0530613 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
janani b0e4e8ae2016-07-13 21:06:41 +0530614 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
615 */
616 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
617
618 YangType referredTypeInLeafOrLeafList;
619 if (yangleafOrLeafList instanceof YangLeaf) {
620 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
621 referredTypeInLeafOrLeafList = leaf.getDataType();
622 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
623 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
624 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
625 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
626 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
627 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
628 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
629 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
630 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
631 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
632 }
633 } else {
634 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
635 referredTypeInLeafOrLeafList = leafList.getDataType();
636 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
637 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
638 unResolvedEntityInfo
639 .setEntityToResolve((YangLeafRef<?>) leafList.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 }
649 }
650
651 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530652 * Returns feature holder(module/sub-module node) .
653 *
654 * @param potentialAncestorWithReferredNode if-feature holder node
655 */
656 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
657 while (potentialAncestorWithReferredNode != null) {
658 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
659 return (YangFeatureHolder) potentialAncestorWithReferredNode;
660 }
661 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
662 }
663 return null;
664 }
665
666 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530667 * Checks if the reference in self file or in external file.
668 *
669 * @return true if self file reference, false otherwise
670 * @throws DataModelException a violation of data model rules
671 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530672 private boolean isCandidateForSelfFileReference()
673 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530674 String prefix = getRefPrefix();
675 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
676 }
677
678 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530679 * Checks for the referred parent node for the leafref path.
680 *
681 * @param potentialReferredNode potential referred node
682 * @return the reffered parent node of leaf/leaf-list
683 * @throws DataModelException data model errors
684 */
685 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
686 throws DataModelException {
687
688 while (potentialReferredNode != null) {
689 if (potentialReferredNode instanceof YangInput) {
690 if (referredNodeName.equalsIgnoreCase(INPUT)) {
691 return potentialReferredNode;
692 }
693 } else if (potentialReferredNode instanceof YangOutput) {
694 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
695 return potentialReferredNode;
696 }
697 }
698 // Check if the potential referred node is the actual referred node
699 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
700 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
701 if (potentialReferredNode.getParent() instanceof YangRpc) {
702 potentialReferredNode = potentialReferredNode.getNextSibling();
703 } else {
704 throw new DataModelException("YANG file error: The target node of leafref is invalid.");
705 }
706 }
707 return potentialReferredNode;
708 }
709 potentialReferredNode = potentialReferredNode.getNextSibling();
710 }
711 return null;
712 }
713
714 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530715 * Checks for the referred parent node for the base/identity.
716 *
717 * @param potentialReferredNode potential referred node
718 * @return the reffered parent node of base/identity.
719 * @throws DataModelException data model errors
720 */
721 private YangNode isReferredNodeInSiblingProcessedForIdentity(YangNode potentialReferredNode,
janani bebb143d2016-07-14 19:35:22 +0530722 String referredNodeName) throws DataModelException {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530723
724 while (potentialReferredNode != null) {
725 if (potentialReferredNode instanceof YangIdentity) {
726 // Check if the potential referred node is the actual referred node
727 if (isReferredNodeForIdentity(potentialReferredNode, referredNodeName)) {
728 return potentialReferredNode;
729 }
730 }
731 potentialReferredNode = potentialReferredNode.getNextSibling();
732 }
733 return null;
734 }
735
736 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530737 * Checks if the current reference node name and the name in the path are equal.
738 *
739 * @param currentReferredNode the node where the reference is pointed
janani bebb143d2016-07-14 19:35:22 +0530740 * @param nameOfNodeinPath name of the node in the path
janani b0e4e8ae2016-07-13 21:06:41 +0530741 * @return status of the match between the name
742 * @throws DataModelException a violation of data model rules
743 */
744 private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
745 throws DataModelException {
746
747 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
748 /*
749 * Check if name of node name matches with the current reference
750 * node.
751 */
752 return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
753 } else {
754 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
755 }
756 }
757
758 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530759 * Checks if the current reference node name and the name in the base/identityref base are equal.
760 *
janani bebb143d2016-07-14 19:35:22 +0530761 * @param currentReferredNode the node where the reference is pointed
Shankara-Huawei234cd092016-07-14 11:35:34 +0530762 * @param nameOfIdentityRefBase name of the base in the base/identityref base
763 * @return status of the match between the name
764 * @throws DataModelException a violation of data model rules
765 */
766 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
767 throws DataModelException {
768
769 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
770 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530771
772 //Check if name of node name matches with the current reference node.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530773 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
774 } else {
775 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref");
776 }
777 }
778
779 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530780 * Checks for the referred node defined in a ancestor scope.
781 *
782 * @param potentialReferredNode potential referred node
783 * @return status of resolution and updating the partial resolved stack with
784 * the any recursive references
janani b0e4e8ae2016-07-13 21:06:41 +0530785 * @throws DataModelException a violation of data model rules
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530786 */
787 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
788 throws DataModelException {
789 while (potentialReferredNode != null) {
790
791 // Check if the potential referred node is the actual referred node
792 if (isReferredNode(potentialReferredNode)) {
793
794 // Adds reference link of entity to the node under resolution.
795 addReferredEntityLink(potentialReferredNode, LINKED);
796
797 /**
798 * resolve the reference and update the partial resolution stack
799 * with any further recursive references
800 */
801 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
802
803 /*
804 * return true, since the reference is linked and any recursive
805 * unresolved references is added to the stack
806 */
807 return true;
808 }
809
810 potentialReferredNode = potentialReferredNode.getNextSibling();
811 }
812 return false;
813 }
814
815 /**
816 * Checks if the potential referred node is the actual referred node.
817 *
818 * @param potentialReferredNode typedef/grouping node
819 * @return true if node is of resolve type otherwise false
820 * @throws DataModelException a violation of data model rules
821 */
822 private boolean isReferredNode(YangNode potentialReferredNode)
823 throws DataModelException {
824 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
825 if (potentialReferredNode instanceof YangTypeDef) {
826 /*
827 * Check if name of node name matches with the entity being
828 * resolved
829 */
830 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
831 }
832 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
833 if (potentialReferredNode instanceof YangGrouping) {
834 /*
835 * Check if name of node name matches with the entity being
836 * resolved
837 */
838 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
839 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530840 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
841 if (potentialReferredNode instanceof YangFeatureHolder) {
842 /*
843 * Check if name of node name matches with the entity being
844 * resolved
845 */
846 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
847 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530848 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
849 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
850 if (potentialReferredNode instanceof YangIdentity) {
851 /*
852 * Check if name of node name matches with the entity being
853 * resolved
854 */
855 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
856 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530857 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530858 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
janani bebb143d2016-07-14 19:35:22 +0530859 "uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530860 }
861 return false;
862 }
863
864 /**
865 * Checks if node name is same as name in resolution info, i.e. name of
866 * typedef/grouping is same as name of type/uses.
867 *
868 * @param node typedef/grouping node
869 * @return true if node name is same as name in resolution info, otherwise
870 * false
871 * @throws DataModelException a violation of data model rules
872 */
873
874 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
875 throws DataModelException {
876 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
877 if (node.getName().contentEquals(
878 ((YangType<?>) getCurrentEntityToResolveFromStack())
879 .getDataTypeName())) {
880 return true;
881 }
882 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
883 if (node.getName().contentEquals(
884 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
885 return true;
886 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530887 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
888 return isFeatureDefinedInNode(node);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530889 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
890 if (node.getName().contentEquals(
891 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
892 return true;
893 }
894 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
895 if (node.getName().contentEquals(
896 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
897 return true;
898 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530899 } else {
900 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
901 }
902 return false;
903 }
904
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530905 private boolean isFeatureDefinedInNode(YangNode node) throws DataModelException {
906 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
907 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
908 if (featureList != null && !featureList.isEmpty()) {
909 Iterator<YangFeature> iterator = featureList.iterator();
910 while (iterator.hasNext()) {
911 YangFeature feature = iterator.next();
912 if (ifFeature.getName().equals(feature.getName())) {
913 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
914 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
915 return true;
916 }
917 }
918 }
919 return false;
920 }
921
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530922 /**
923 * Adds reference of grouping/typedef in uses/type.
924 *
925 * @param referredNode grouping/typedef node being referred
926 * @param linkedStatus linked status if success.
927 * @throws DataModelException a violation of data model rules
928 */
929 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
930 throws DataModelException {
931 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530932 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
933 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530934 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
935 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
936 ((YangUses) getCurrentEntityToResolveFromStack())
937 .setRefGroup((YangGrouping) referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530938 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
939 // do nothing , referred node is already set
janani b0e4e8ae2016-07-13 21:06:41 +0530940 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
941 // do nothing , referred node is already set
Shankara-Huawei234cd092016-07-14 11:35:34 +0530942 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
943 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
944 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
945 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530946 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530947 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +0530948 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530949 }
950
951 // Sets the resolution status in inside the type/uses.
952 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
953 }
954
955 /**
956 * Checks if type/grouping has further reference to typedef/ unresolved
957 * uses. Add it to the partial resolve stack and return the status of
958 * addition to stack.
959 *
960 * @param referredNode grouping/typedef node
961 * @throws DataModelException a violation of data model rules
962 */
963 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
964 throws DataModelException {
965 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530966
967 //Checks if typedef type is derived
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530968 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530969
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530970 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530971 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
972 .getTypeDefBaseType());
973 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530974 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530975 }
976
977 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
978 /*
979 * Search if the grouping has any un resolved uses child, if so
980 * return true, else return false.
981 */
982 addUnResolvedUsesToStack(referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530983 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
984 addUnResolvedIfFeatureToStack(referredNode);
janani b0e4e8ae2016-07-13 21:06:41 +0530985 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
986 // do nothing , referred node is already set
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530987 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
Shankara-Huawei234cd092016-07-14 11:35:34 +0530988 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
989 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530990
991 //Search if the identity has any un resolved base, if so return true, else return false.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530992 addUnResolvedBaseToStack(referredNode);
993 } else {
994 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
janani bebb143d2016-07-14 19:35:22 +0530995 "base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530996 }
997 }
998
999 /**
1000 * Returns if there is any unresolved uses in grouping.
1001 *
1002 * @param node grouping/typedef node
1003 */
1004 private void addUnResolvedUsesToStack(YangNode node) {
1005
Vidyashree Ramab3670472016-08-06 15:49:56 +05301006 //Search the grouping node's children for presence of uses node.
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301007 TraversalType curTraversal = ROOT;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301008 YangNode curNode = node.getChild();
1009 while (curNode != null) {
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301010 if (curNode.getName().equals(node.getName())) {
1011 // if we have traversed all the child nodes, then exit from loop
1012 return;
1013 }
1014
1015 // if child nodes has uses, then add it to resolution stack
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301016 if (curNode instanceof YangUses) {
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301017 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301018 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1019 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301020 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301021 }
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301022
1023 // Traversing all the child nodes of grouping
1024 if (curTraversal != PARENT && curNode.getChild() != null) {
1025 curTraversal = CHILD;
1026 curNode = curNode.getChild();
1027 } else if (curNode.getNextSibling() != null) {
1028 curTraversal = SIBILING;
1029 curNode = curNode.getNextSibling();
1030 } else {
1031 curTraversal = PARENT;
1032 curNode = curNode.getParent();
1033 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301034 }
1035 }
1036
1037 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301038 * Returns if there is any unresolved if-feature in feature.
1039 *
1040 * @param node module/submodule node
1041 */
1042 private void addUnResolvedIfFeatureToStack(YangNode node) {
1043 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1044 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1045 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1046 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1047 while (ifFeatureIterator.hasNext()) {
1048 YangIfFeature ifFeature = ifFeatureIterator.next();
1049 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1050 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1051 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1052 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1053 }
1054 }
1055 }
1056
1057 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +05301058 * Returns if there is any unresolved base in identity.
1059 *
1060 * @param node module/submodule node
1061 */
1062 private void addUnResolvedBaseToStack(YangNode node) {
1063
1064 YangIdentity curNode = (YangIdentity) node;
1065 if (curNode.getBaseNode() != null) {
1066 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1067 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1068 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1069 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1070 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1071
1072 }
1073 }
1074 }
1075
1076
1077 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301078 * Returns stack of YANG type with partially resolved YANG construct
1079 * hierarchy.
1080 *
1081 * @return partial resolved YANG construct stack
1082 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301083 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301084 return partialResolvedStack;
1085 }
1086
1087 /**
1088 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1089 *
1090 * @param partialResolvedStack partial resolved YANG construct stack
1091 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301092 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301093 this.partialResolvedStack = partialResolvedStack;
1094 }
1095
1096 /**
1097 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1098 *
1099 * @param partialResolvedInfo partial resolved YANG construct stack
1100 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301101 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301102 getPartialResolvedStack().push(partialResolvedInfo);
1103 }
1104
1105 /**
1106 * Retrieves the next entity in the stack that needs to be resolved. It is
1107 * assumed that the caller ensures that the stack is not empty.
1108 *
1109 * @return next entity in the stack that needs to be resolved
1110 */
1111 private T getCurrentEntityToResolveFromStack() {
1112 return getPartialResolvedStack().peek().getEntityToResolve();
1113 }
1114
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301115 @Override
1116 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301117 return entityToResolveInfo;
1118 }
1119
1120 /**
1121 * Sets information about the entity that needs to be resolved.
1122 *
1123 * @param entityToResolveInfo information about the entity that needs to be
1124 * resolved
1125 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301126 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301127 this.entityToResolveInfo = entityToResolveInfo;
1128 }
1129
1130 @Override
1131 public int getLineNumber() {
1132 return lineNumber;
1133 }
1134
1135 @Override
1136 public int getCharPosition() {
1137 return charPosition;
1138 }
1139
1140 @Override
1141 public void setLineNumber(int lineNumber) {
1142 this.lineNumber = lineNumber;
1143 }
1144
1145 @Override
1146 public void setCharPosition(int charPositionInLine) {
1147 this.charPosition = charPositionInLine;
1148 }
1149
1150 /**
1151 * Returns current module/sub-module reference, will be used in inter-file/
1152 * inter-jar scenario to get the import/include list.
1153 *
1154 * @return current module/sub-module reference
1155 */
1156 private YangReferenceResolver getCurReferenceResolver() {
1157 return curReferenceResolver;
1158 }
1159
1160 /**
1161 * Sets current module/sub-module reference, will be used in inter-file/
1162 * inter-jar scenario to get the import/include list.
1163 *
1164 * @param curReferenceResolver current module/sub-module reference
1165 */
1166 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1167 this.curReferenceResolver = curReferenceResolver;
1168 }
1169
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301170 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301171 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1172 throws DataModelException {
1173
1174 setCurReferenceResolver(dataModelRootNode);
1175
1176 // Current node to resolve, it can be a YANG type or YANG uses.
1177 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1178
1179 // Check if linking is already done
1180 if (entityToResolve instanceof Resolvable) {
1181 Resolvable resolvable = (Resolvable) entityToResolve;
1182 if (resolvable.getResolvableStatus() == RESOLVED) {
1183 return;
1184 }
1185 } else {
1186 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1187 }
1188
janani bebb143d2016-07-14 19:35:22 +05301189 if (entityToResolve instanceof YangXPathResolver && !(entityToResolve instanceof YangLeafRef)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +05301190 //Process x-path linking.
janani bebb143d2016-07-14 19:35:22 +05301191 processXPathLinking(entityToResolve, dataModelRootNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301192
Bharat saraswald14cbe82016-07-14 13:26:18 +05301193 } else {
janani b0e4e8ae2016-07-13 21:06:41 +05301194
Bharat saraswald14cbe82016-07-14 13:26:18 +05301195 // Push the initial entity to resolve in stack.
1196 addInPartialResolvedStack(getEntityToResolveInfo());
1197
1198 // Inter file linking and resolution.
1199 linkInterFileAndResolve();
1200
1201 addDerivedRefTypeToRefTypeResolutionList();
1202 }
1203 }
1204
1205 /**
1206 * Process x-path linking for augment and leaf-ref.
1207 *
janani bebb143d2016-07-14 19:35:22 +05301208 * @param entityToResolve entity to resolve
1209 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +05301210 */
janani bebb143d2016-07-14 19:35:22 +05301211 private void processXPathLinking(T entityToResolve,
Bharat saraswald14cbe82016-07-14 13:26:18 +05301212 YangReferenceResolver root) {
janani bebb143d2016-07-14 19:35:22 +05301213
Bharat saraswald14cbe82016-07-14 13:26:18 +05301214 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
janani bebb143d2016-07-14 19:35:22 +05301215
Bharat saraswald14cbe82016-07-14 13:26:18 +05301216 if (entityToResolve instanceof YangAugment) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301217 YangNode targetNode = null;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301218 YangAugment augment = (YangAugment) entityToResolve;
1219 targetNode = xPathLinker.processAugmentXpathLinking(augment.getTargetNode(),
1220 (YangNode) root);
1221 if (targetNode != null) {
1222 if (targetNode instanceof YangAugmentableNode) {
1223 detectCollisionForAugmentedNode(targetNode, augment);
1224 ((YangAugmentableNode) targetNode).addAugmentation(augment);
1225 augment.setAugmentedNode(targetNode);
1226 Resolvable resolvable = (Resolvable) entityToResolve;
1227 resolvable.setResolvableStatus(RESOLVED);
1228 } else {
1229 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for "
1230 + augment.getName());
1231 }
1232 } else {
1233 throw new LinkerException("Failed to link " + augment.getName());
1234 }
Vidyashree Ramab3670472016-08-06 15:49:56 +05301235 } else if (entityToResolve instanceof YangCompilerAnnotation) {
1236 YangNode targetNode;
1237 YangCompilerAnnotation ca = (YangCompilerAnnotation) entityToResolve;
1238
1239 targetNode = xPathLinker.processAugmentXpathLinking(ca.getAtomicPathList(),
1240 (YangNode) root);
1241 if (targetNode != null) {
1242 if (targetNode instanceof YangList) {
1243 ((YangList) targetNode).setCompilerAnnotation(
1244 (YangCompilerAnnotation) entityToResolve);
1245 Resolvable resolvable = (Resolvable) entityToResolve;
1246 resolvable.setResolvableStatus(RESOLVED);
1247 } else {
1248 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for compiler" +
1249 " annotation " + ca.getPath());
1250 }
1251 } else {
1252 throw new LinkerException("Failed to link compiler annotation " + ca.getPath());
1253 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301254 } else if (entityToResolve instanceof YangLeafRef) {
1255 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
1256 Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
janani bebb143d2016-07-14 19:35:22 +05301257 (YangNode) root, leafRef);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301258 if (target != null) {
1259 YangLeaf leaf = null;
1260 YangLeafList leafList = null;
1261 leafRef.setReferredLeafOrLeafList(target);
1262 if (target instanceof YangLeaf) {
1263 leaf = (YangLeaf) target;
janani bebb143d2016-07-14 19:35:22 +05301264 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1265 addUnResolvedLeafRefTypeToStack((T) leaf, getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301266 } else {
1267 leafList = (YangLeafList) target;
janani bebb143d2016-07-14 19:35:22 +05301268 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1269 addUnResolvedLeafRefTypeToStack((T) leafList,
1270 getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301271 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301272 //TODO: add logic for leaf-ref for path predicates.
1273 } else {
janani bebb143d2016-07-14 19:35:22 +05301274 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
1275 "leaf/leaf-list for given leafref path "
Bharat saraswald14cbe82016-07-14 13:26:18 +05301276 + leafRef.getPath());
janani bebb143d2016-07-14 19:35:22 +05301277 linkerException.setCharPosition(leafRef.getCharPosition());
1278 linkerException.setLine(leafRef.getLineNumber());
1279 throw linkerException;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301280 }
1281 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301282 }
1283
1284 /**
1285 * Returns the referenced prefix of entity under resolution.
1286 *
1287 * @return referenced prefix of entity under resolution
1288 * @throws DataModelException a violation in data model rule
1289 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301290 private String getRefPrefix()
1291 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301292 String refPrefix;
1293 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1294 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1295 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1296 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301297 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1298 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301299 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1300 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1301 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1302 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301303 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301304 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
janani bebb143d2016-07-14 19:35:22 +05301305 "type/uses/base/identityref");
janani b0e4e8ae2016-07-13 21:06:41 +05301306 }
1307 return refPrefix;
1308 }
1309
1310 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301311 * Performs inter file linking and resolution.
1312 *
1313 * @throws DataModelException a violation in data model rule
1314 */
1315 private void linkInterFileAndResolve()
1316 throws DataModelException {
1317
1318 while (getPartialResolvedStack().size() != 0) {
1319
1320 // Current node to resolve, it can be a YANG type or YANG uses.
1321 T entityToResolve = getCurrentEntityToResolveFromStack();
1322 // Check if linking is already done
1323 if (entityToResolve instanceof Resolvable) {
1324
1325 Resolvable resolvable = (Resolvable) entityToResolve;
1326 switch (resolvable.getResolvableStatus()) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301327 case RESOLVED: {
1328 /*
1329 * If the entity is already resolved in the stack, then pop
1330 * it and continue with the remaining stack elements to
1331 * resolve
1332 */
1333 getPartialResolvedStack().pop();
1334 break;
1335 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301336
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301337 case INTER_FILE_LINKED: {
1338 /*
1339 * If the top of the stack is already linked then resolve
1340 * the references and pop the entity and continue with
1341 * remaining stack elements to resolve
1342 */
1343 resolveTopOfStack(INTER_FILE);
1344 getPartialResolvedStack().pop();
1345 break;
1346 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301347
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301348 case INTRA_FILE_RESOLVED: {
1349 /*
1350 * If the top of the stack is intra file resolved then check
1351 * if top of stack is linked, if not link it using
1352 * import/include list and push the linked referred entity
1353 * to the stack, otherwise only push it to the stack.
1354 */
1355 linkInterFileTopOfStackRefUpdateStack();
1356 break;
1357 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301358
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301359 case UNDEFINED: {
1360 /*
1361 * In case of if-feature resolution, if referred "feature" is not
1362 * defined then the resolvable status will be undefined.
1363 */
1364 getPartialResolvedStack().pop();
1365 break;
1366 }
1367
1368 default: {
1369 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1370 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301371
1372 }
1373
1374 } else {
1375 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1376 }
1377
1378 }
1379
1380 }
1381
1382 /**
1383 * Links the top of the stack if it's inter-file and update stack.
1384 *
1385 * @throws DataModelException data model error
1386 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301387 private void linkInterFileTopOfStackRefUpdateStack()
1388 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301389
janani bebb143d2016-07-14 19:35:22 +05301390 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1391 // When leafref path comes with relative path, it will be converted to absolute path.
1392 setAbsolutePathFromRelativePathInLeafref(getCurrentEntityToResolveFromStack());
1393 processXPathLinking(getCurrentEntityToResolveFromStack(), getCurReferenceResolver());
1394 return;
1395 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301396 /*
1397 * Obtain the referred node of top of stack entity under resolution
1398 */
1399 T referredNode = getRefNode();
1400
1401 /*
1402 * Check for null for scenario when it's not linked and inter-file
1403 * linking is required.
1404 */
1405 if (referredNode == null) {
1406
1407 /*
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301408 * Check if prefix is null or not, to identify whether to search in
1409 * import list or include list.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301410 */
Bharat saraswal5cd9e9c2016-05-26 23:48:38 +05301411 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301412 if (resolveWithImport()) {
1413 return;
1414 }
1415 } else {
1416 if (resolveWithInclude()) {
1417 return;
1418 }
1419 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301420
1421 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1422 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1423 return;
1424 }
janani b0e4e8ae2016-07-13 21:06:41 +05301425 // If current entity is still not resolved, then
1426 // linking/resolution has failed.
1427 String errorInfo;
1428 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1429 errorInfo = TYPEDEF_LINKER_ERROR;
1430 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1431 errorInfo = GROUPING_LINKER_ERROR;
1432 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1433 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huawei234cd092016-07-14 11:35:34 +05301434 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1435 errorInfo = BASE_LINKER_ERROR;
1436 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1437 errorInfo = IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +05301438 } else {
1439 errorInfo = LEAFREF_LINKER_ERROR;
1440 }
1441 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301442 dataModelException.setLine(getLineNumber());
1443 dataModelException.setCharPosition(getCharPosition());
1444 throw dataModelException;
1445 } else {
janani bebb143d2016-07-14 19:35:22 +05301446 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1447 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1448 }
1449 }
1450
1451 /**
1452 * Sets the leafref with absolute path from the relative path.
1453 *
1454 * @param resolutionInfo information about the YANG construct which has to be resolved
1455 * @throws DataModelException a violation of data model rules
1456 */
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301457 public void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo) throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301458 if (resolutionInfo instanceof YangLeafRef) {
1459
1460 YangNode parentOfLeafref = ((YangLeafRef) resolutionInfo).getParentNodeOfLeafref();
1461 YangLeafRef leafref = (YangLeafRef) resolutionInfo;
1462
1463 // Checks if the leafref has relative path in it.
1464 if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
1465 YangRelativePath relativePath = leafref.getRelativePath();
1466 List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
1467 int numberOfAncestors = relativePath.getAncestorNodeCount();
1468
1469 // Gets the root node from the ancestor count.
1470 T nodeOrAugmentList = getRootNodeWithAncestorCountForLeafref(numberOfAncestors, parentOfLeafref,
1471 leafref);
1472 if (nodeOrAugmentList instanceof YangNode) {
1473 String pathNameToBePrefixed = EMPTY_STRING;
1474 YangNode rootNode = (YangNode) nodeOrAugmentList;
1475 // Forms a new absolute path from the relative path
1476 while (!(rootNode instanceof YangReferenceResolver)) {
1477 pathNameToBePrefixed = rootNode.getName() + SLASH_FOR_STRING + pathNameToBePrefixed;
1478 rootNode = rootNode.getParent();
1479 if (rootNode == null) {
1480 throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
1481 }
1482 }
1483 fillAbsolutePathValuesInLeafref(leafref, pathNameToBePrefixed, absoluteInRelative);
1484 } else {
1485 List<String> listOfAugment = (List<String>) nodeOrAugmentList;
1486 Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
1487 String augment = EMPTY_STRING;
1488 while (listOfAugmentIterator.hasNext()) {
1489 augment = augment + SLASH_FOR_STRING + listOfAugmentIterator.next();
1490 }
1491 fillAbsolutePathValuesInLeafref(leafref, augment, absoluteInRelative);
janani b0e4e8ae2016-07-13 21:06:41 +05301492 }
janani b0e4e8ae2016-07-13 21:06:41 +05301493 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301494 }
1495 }
1496
1497 /**
janani bebb143d2016-07-14 19:35:22 +05301498 * Fills the absolute path values in the leafref from relative path.
1499 *
Bharat saraswal8beac342016-08-04 02:00:03 +05301500 * @param leafref instance of YANG leafref
1501 * @param pathNameToBePrefixed path name which has to be prefixed to relative path
1502 * @param atomicPathsInRelative atomic paths in relative
janani bebb143d2016-07-14 19:35:22 +05301503 * @throws DataModelException a violation of data model rules
1504 */
1505 private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String pathNameToBePrefixed,
1506 List<YangAtomicPath> atomicPathsInRelative) throws DataModelException {
1507
1508 leafref.setPathType(YangPathArgType.ABSOLUTE_PATH);
1509 String[] pathName = new String[0];
1510 if (pathNameToBePrefixed != EMPTY_STRING && pathNameToBePrefixed != null) {
1511 pathName = pathNameToBePrefixed.split(SLASH_FOR_STRING);
1512 }
1513 List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
1514 for (String value : pathName) {
1515 if (value != null && !value.isEmpty() && value != EMPTY_STRING) {
1516 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(value, YangConstructType.PATH_DATA);
1517 YangAtomicPath atomicPath = new YangAtomicPath();
1518 atomicPath.setNodeIdentifier(nodeIdentifier);
1519 finalListForAbsolute.add(atomicPath);
1520 }
1521 }
1522 if (atomicPathsInRelative != null && !atomicPathsInRelative.isEmpty()) {
1523 Iterator<YangAtomicPath> atomicPathIterator = atomicPathsInRelative.listIterator();
1524 while (atomicPathIterator.hasNext()) {
1525 YangAtomicPath yangAtomicPath = atomicPathIterator.next();
1526 finalListForAbsolute.add(yangAtomicPath);
1527 }
1528 leafref.setAtomicPath(finalListForAbsolute);
1529 } else {
1530 DataModelException dataModelException = new DataModelException("YANG file error: The target node, in the " +
1531 "leafref path " + leafref.getPath() + ", is invalid.");
1532 dataModelException.setCharPosition(leafref.getCharPosition());
1533 dataModelException.setLine(leafref.getLineNumber());
1534 throw dataModelException;
1535 }
1536 }
1537
1538 /**
1539 * Returns the root parent with respect to the ancestor count from leafref.
1540 *
1541 * @param ancestorCount count of node where parent node can be reached
1542 * @param currentParent current parent node
1543 * @param leafref instance of YANG leafref
1544 * @return node where the ancestor count stops or augment path name list
1545 * @throws DataModelException a violation of data model rules
1546 */
1547 private T getRootNodeWithAncestorCountForLeafref(int ancestorCount, YangNode currentParent, YangLeafRef leafref)
1548 throws DataModelException {
1549
1550 int currentParentCount = 1;
1551 currentParent = skipInvalidDataNodes(currentParent, leafref);
1552 if (currentParent instanceof YangAugment) {
1553 YangAugment augment = (YangAugment) currentParent;
1554 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1555 return (T) valueInAugment;
1556 } else {
1557 while (currentParentCount < ancestorCount) {
1558 YangNode currentSkippedParent = skipInvalidDataNodes(currentParent, leafref);
1559 if (currentSkippedParent == currentParent) {
1560 if (currentParent.getParent() == null) {
1561 throw new DataModelException("YANG file error: The target node, in the leafref path "
1562 + leafref.getPath() + ", is invalid.");
1563 }
1564 currentParent = currentParent.getParent();
1565 } else {
1566 currentParent = currentSkippedParent;
1567 continue;
1568 }
1569 currentParentCount = currentParentCount + 1;
1570 if (currentParent instanceof YangAugment) {
1571 YangAugment augment = (YangAugment) currentParent;
1572 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1573 return (T) valueInAugment;
1574 }
1575 }
1576 }
1577 return (T) currentParent;
1578 }
1579
1580 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301581 * Finds and resolves with include list.
1582 *
1583 * @return true if resolved, false otherwise
1584 * @throws DataModelException a violation in data model rule
1585 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301586 private boolean resolveWithInclude()
1587 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301588 /*
1589 * Run through all the nodes in include list and search for referred
1590 * typedef/grouping at the root level.
1591 */
1592 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1593 YangNode linkedNode = null;
1594 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1595 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1596 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1597 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301598 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1599 linkedNode = findRefFeature(yangInclude.getIncludedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301600 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1601 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1602 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1603 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301604 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301605
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301606 if (linkedNode != null) {
1607 // Add the link to external entity.
1608 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301609
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301610 // Add the type/uses of referred typedef/grouping to the stack.
1611 addUnresolvedRecursiveReferenceToStack(linkedNode);
1612 return true;
1613 }
1614 }
1615 // If referred node can't be found return false.
1616 return false;
1617 }
1618
1619 /**
1620 * Finds and resolves with import list.
1621 *
1622 * @return true if resolved, false otherwise
1623 * @throws DataModelException a violation in data model rule
1624 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301625 private boolean resolveWithImport()
1626 throws DataModelException {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301627
1628 // Run through import list to find the referred typedef/grouping.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301629 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1630 /*
1631 * Match the prefix attached to entity under resolution with the
1632 * imported/included module/sub-module's prefix. If found, search
1633 * for the referred typedef/grouping at the root level.
1634 */
1635 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1636 YangNode linkedNode = null;
1637 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1638 linkedNode = findRefTypedef(yangImport.getImportedNode());
1639 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1640 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301641 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1642 linkedNode = findRefFeature(yangImport.getImportedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301643 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1644 linkedNode = findRefIdentity(yangImport.getImportedNode());
1645 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1646 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301647 }
1648 if (linkedNode != null) {
1649 // Add the link to external entity.
1650 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301651
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301652 // Add the type/uses of referred typedef/grouping to the
1653 // stack.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301654 addUnresolvedRecursiveReferenceToStack(linkedNode);
1655 return true;
1656 }
1657 /*
1658 * If referred node can't be found at root level break for loop,
1659 * and return false.
1660 */
1661 break;
1662 }
1663 }
1664 // If referred node can't be found return false.
1665 return false;
1666 }
1667
1668 /**
1669 * Returns referred typedef/grouping node.
1670 *
1671 * @return referred typedef/grouping node
1672 * @throws DataModelException a violation in data model rule
1673 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301674 private T getRefNode()
1675 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301676 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301677 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1678 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301679 return (T) derivedInfo.getReferredTypeDef();
1680 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1681 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301682 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1683 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani b0e4e8ae2016-07-13 21:06:41 +05301684 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1685 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301686 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1687 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1688 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1689 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301690 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301691 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +05301692 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301693 }
1694 }
1695
1696 /**
1697 * Finds the referred grouping node at the root level of imported/included node.
1698 *
1699 * @param refNode module/sub-module node
1700 * @return referred grouping
1701 */
1702 private YangNode findRefGrouping(YangNode refNode) {
1703 YangNode tmpNode = refNode.getChild();
1704 while (tmpNode != null) {
1705 if (tmpNode instanceof YangGrouping) {
1706 if (tmpNode.getName()
1707 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1708 return tmpNode;
1709 }
1710 }
1711 tmpNode = tmpNode.getNextSibling();
1712 }
1713 return null;
1714 }
1715
1716 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301717 * Finds the referred feature node at the root level of imported/included node.
1718 *
1719 * @param refNode module/sub-module node
1720 * @return referred feature
1721 */
1722 private YangNode findRefFeature(YangNode refNode) {
1723 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1724 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1725
1726 if (featureList != null && !featureList.isEmpty()) {
1727 Iterator<YangFeature> iterator = featureList.iterator();
1728 while (iterator.hasNext()) {
1729 YangFeature feature = iterator.next();
1730 if (ifFeature.getName().equals(feature.getName())) {
1731 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1732 return refNode;
1733 }
1734 }
1735 }
1736 return null;
1737 }
1738
1739 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301740 * Finds the referred typedef node at the root level of imported/included node.
1741 *
1742 * @param refNode module/sub-module node
1743 * @return referred typedef
1744 */
1745 private YangNode findRefTypedef(YangNode refNode) {
1746 YangNode tmpNode = refNode.getChild();
1747 while (tmpNode != null) {
1748 if (tmpNode instanceof YangTypeDef) {
1749 if (tmpNode.getName()
1750 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1751 return tmpNode;
1752 }
1753 }
1754 tmpNode = tmpNode.getNextSibling();
1755 }
1756 return null;
1757 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301758
1759 /**
1760 * Finds the referred identity node at the root level of imported/included node.
1761 *
1762 * @param refNode module/sub-module node
1763 * @return referred identity
1764 */
1765 private YangNode findRefIdentity(YangNode refNode) {
1766 YangNode tmpNode = refNode.getChild();
1767 while (tmpNode != null) {
1768 if (tmpNode instanceof YangIdentity) {
1769 if (tmpNode.getName()
1770 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1771 return tmpNode;
1772 }
1773 }
1774 tmpNode = tmpNode.getNextSibling();
1775 }
1776 return null;
1777 }
1778
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 findRefIdentityRef(YangNode refNode) {
1786 YangNode tmpNode = refNode.getChild();
1787 while (tmpNode != null) {
1788 if (tmpNode instanceof YangIdentity) {
1789 if (tmpNode.getName()
1790 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
janani bebb143d2016-07-14 19:35:22 +05301791 .getBaseIdentity().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301792 return tmpNode;
1793 }
1794 }
1795 tmpNode = tmpNode.getNextSibling();
1796 }
1797 return null;
1798 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301799}