blob: 1281bb8c9363f94db1a74173c150e7e56be263f0 [file] [log] [blame]
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yangutils.linker.impl;
18
Vidyashree Rama72719fa2016-07-15 14:06:56 +053019import java.io.Serializable;
20import java.util.Iterator;
21import java.util.LinkedList;
22import java.util.List;
23import java.util.Stack;
VinodKumarS-Huawei3b4cce02016-08-20 21:32:17 +053024
Bharat saraswale3175d32016-08-31 17:50:11 +053025import org.onosproject.yangutils.datamodel.DefaultLocationInfo;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053026import org.onosproject.yangutils.datamodel.Resolvable;
janani b0e4e8ae2016-07-13 21:06:41 +053027import org.onosproject.yangutils.datamodel.ResolvableType;
Vidyashree Rama72719fa2016-07-15 14:06:56 +053028import org.onosproject.yangutils.datamodel.TraversalType;
janani b0e4e8ae2016-07-13 21:06:41 +053029import org.onosproject.yangutils.datamodel.YangAtomicPath;
Bharat saraswald14cbe82016-07-14 13:26:18 +053030import org.onosproject.yangutils.datamodel.YangAugment;
31import org.onosproject.yangutils.datamodel.YangAugmentableNode;
Shankara-Huawei234cd092016-07-14 11:35:34 +053032import org.onosproject.yangutils.datamodel.YangBase;
Vidyashree Ramab3670472016-08-06 15:49:56 +053033import org.onosproject.yangutils.datamodel.YangCompilerAnnotation;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053034import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053035import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
janani bebb143d2016-07-14 19:35:22 +053036import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053037import org.onosproject.yangutils.datamodel.YangFeature;
38import org.onosproject.yangutils.datamodel.YangFeatureHolder;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053039import org.onosproject.yangutils.datamodel.YangGrouping;
Shankara-Huawei234cd092016-07-14 11:35:34 +053040import org.onosproject.yangutils.datamodel.YangIdentity;
41import org.onosproject.yangutils.datamodel.YangIdentityRef;
Bharat saraswalaf413b82016-07-14 15:18:20 +053042import org.onosproject.yangutils.datamodel.YangIfFeature;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053043import org.onosproject.yangutils.datamodel.YangImport;
44import org.onosproject.yangutils.datamodel.YangInclude;
janani b0e4e8ae2016-07-13 21:06:41 +053045import org.onosproject.yangutils.datamodel.YangInput;
46import org.onosproject.yangutils.datamodel.YangLeaf;
47import org.onosproject.yangutils.datamodel.YangLeafList;
48import org.onosproject.yangutils.datamodel.YangLeafRef;
Vidyashree Ramab3670472016-08-06 15:49:56 +053049import org.onosproject.yangutils.datamodel.YangList;
janani b0e4e8ae2016-07-13 21:06:41 +053050import org.onosproject.yangutils.datamodel.YangModule;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053051import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053052import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
janani b0e4e8ae2016-07-13 21:06:41 +053053import org.onosproject.yangutils.datamodel.YangOutput;
54import org.onosproject.yangutils.datamodel.YangPathArgType;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053055import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani b0e4e8ae2016-07-13 21:06:41 +053056import org.onosproject.yangutils.datamodel.YangRelativePath;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053057import org.onosproject.yangutils.datamodel.YangResolutionInfo;
janani b0e4e8ae2016-07-13 21:06:41 +053058import org.onosproject.yangutils.datamodel.YangRpc;
59import org.onosproject.yangutils.datamodel.YangSubModule;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053060import org.onosproject.yangutils.datamodel.YangType;
61import org.onosproject.yangutils.datamodel.YangTypeDef;
62import org.onosproject.yangutils.datamodel.YangUses;
Bharat saraswald14cbe82016-07-14 13:26:18 +053063import org.onosproject.yangutils.datamodel.YangXPathResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053064import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053065import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
janani bebb143d2016-07-14 19:35:22 +053066import org.onosproject.yangutils.datamodel.utils.YangConstructType;
janani b0e4e8ae2016-07-13 21:06:41 +053067import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +053068import org.onosproject.yangutils.linker.YangLinkingPhase;
Bharat saraswald14cbe82016-07-14 13:26:18 +053069import org.onosproject.yangutils.linker.exceptions.LinkerException;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053070
Vidyashree Rama72719fa2016-07-15 14:06:56 +053071import static org.onosproject.yangutils.datamodel.TraversalType.CHILD;
72import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
73import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
74import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
janani bebb143d2016-07-14 19:35:22 +053075import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053076import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
77import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
78import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.LINKED;
79import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053080import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNDEFINED;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053081import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +053082import static org.onosproject.yangutils.linker.YangLinkingPhase.INTER_FILE;
83import static org.onosproject.yangutils.linker.YangLinkingPhase.INTRA_FILE;
Bharat saraswald14cbe82016-07-14 13:26:18 +053084import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
janani bebb143d2016-07-14 19:35:22 +053085import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
86import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getValidNodeIdentifier;
87import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.skipInvalidDataNodes;
Bharat saraswalaf413b82016-07-14 15:18:20 +053088import static org.onosproject.yangutils.utils.UtilConstants.BASE_LINKER_ERROR;
janani bebb143d2016-07-14 19:35:22 +053089import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
Vidyashree Rama13b4c552016-06-20 15:12:43 +053090import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
Vidyashree Rama5daea742016-05-20 16:29:25 +053091import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
Bharat saraswalaf413b82016-07-14 15:18:20 +053092import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
93import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +053094import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
95import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
96import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
97import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
janani bebb143d2016-07-14 19:35:22 +053098import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053099import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530100
101/**
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530102 * Represents implementation of resolution object which will be resolved by
103 * linker.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530104 *
105 * @param <T> type of resolution entity uses / type
106 */
Bharat saraswale3175d32016-08-31 17:50:11 +0530107public class YangResolutionInfoImpl<T> extends DefaultLocationInfo
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530108 implements YangResolutionInfo<T>, Serializable {
109
110 private static final long serialVersionUID = 806201658L;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530111
112 /**
113 * Information about the entity that needs to be resolved.
114 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530115 private YangEntityToResolveInfoImpl<T> entityToResolveInfo;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530116
117 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530118 * Current module/sub-module reference, will be used in inter-file/
119 * inter-jar scenario to get the import/include list.
120 */
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530121 private YangReferenceResolver curReferenceResolver;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530122
123 /**
124 * Stack for type/uses is maintained for hierarchical references, this is
125 * used during resolution.
126 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530127 private Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530128
129 /**
130 * It is private to ensure the overloaded method be invoked to create an
131 * object.
132 */
133 @SuppressWarnings("unused")
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530134 private YangResolutionInfoImpl() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530135 }
136
137 /**
138 * Creates a resolution information object with all the inputs.
139 *
140 * @param dataNode current parsable data node
141 * @param holderNode parent YANG node
142 * @param lineNumber error line number
143 * @param charPositionInLine error character position in line
144 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530145 public YangResolutionInfoImpl(T dataNode, YangNode holderNode, int lineNumber, int charPositionInLine) {
146 setEntityToResolveInfo(new YangEntityToResolveInfoImpl<>());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530147 getEntityToResolveInfo().setEntityToResolve(dataNode);
148 getEntityToResolveInfo().setHolderOfEntityToResolve(holderNode);
149 this.setLineNumber(lineNumber);
150 this.setCharPosition(charPositionInLine);
151 setPartialResolvedStack(new Stack<>());
152 }
153
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530154 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530155 public void resolveLinkingForResolutionInfo(YangReferenceResolver dataModelRootNode)
156 throws DataModelException {
157
158 setCurReferenceResolver(dataModelRootNode);
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530159 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530160 * Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or
161 * YANG leafref or YANG base or YANG identityref.
162 */
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530163 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
164
165 // Check if linking is already done
166 if (entityToResolve instanceof Resolvable) {
167 Resolvable resolvable = (Resolvable) entityToResolve;
168 if (resolvable.getResolvableStatus() == RESOLVED) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530169 /*
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530170 * entity is already resolved, so nothing to do
171 */
172 return;
173 }
174 } else {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530175 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
Shankara-Huawei234cd092016-07-14 11:35:34 +0530176 "type/uses/if-feature/leafref/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530177 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530178 // Push the initial entity to resolve in stack.
179 addInPartialResolvedStack(getEntityToResolveInfo());
180
181 linkAndResolvePartialResolvedStack();
janani b0e4e8ae2016-07-13 21:06:41 +0530182
183 addDerivedRefTypeToRefTypeResolutionList();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530184 }
185
186 /**
187 * Resolves linking with ancestors.
188 *
189 * @throws DataModelException a violation of data model rules
190 */
191 private void linkAndResolvePartialResolvedStack()
192 throws DataModelException {
193
194 while (getPartialResolvedStack().size() != 0) {
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530195 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530196 * Current node to resolve, it can be a YANG type or YANG uses or
197 * YANG if-feature or YANG leafref or YANG base or YANG identityref.
198 */
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530199 T entityToResolve = getCurrentEntityToResolveFromStack();
200 // Check if linking is already done
201 if (entityToResolve instanceof Resolvable) {
202
203 Resolvable resolvable = (Resolvable) entityToResolve;
204 switch (resolvable.getResolvableStatus()) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530205 case RESOLVED: {
206 /*
207 * If the entity is already resolved in the stack, then pop
208 * it and continue with the remaining stack elements to
209 * resolve
210 */
211 getPartialResolvedStack().pop();
212 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530213 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530214
215 case LINKED: {
216 /*
217 * If the top of the stack is already linked then resolve
218 * the references and pop the entity and continue with
219 * remaining stack elements to resolve.
220 */
221 resolveTopOfStack(INTRA_FILE);
222 getPartialResolvedStack().pop();
223 break;
224 }
225
226 case INTRA_FILE_RESOLVED: {
227 /*
228 * Pop the top of the stack.
229 */
230 getPartialResolvedStack().pop();
231 break;
232 }
233
234 case UNRESOLVED: {
235 linkTopOfStackReferenceUpdateStack();
236
237 if (resolvable.getResolvableStatus() == UNRESOLVED) {
238 // If current entity is still not resolved, then
239 // linking/resolution has failed.
240 String errorInfo;
241 if (resolvable instanceof YangType) {
242 errorInfo = TYPEDEF_LINKER_ERROR;
243 } else if (resolvable instanceof YangUses) {
244 errorInfo = GROUPING_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +0530245 } else if (resolvable instanceof YangIfFeature) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530246 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530247 } else if (resolvable instanceof YangBase) {
248 errorInfo = BASE_LINKER_ERROR;
249 } else if (resolvable instanceof YangIdentityRef) {
250 errorInfo = IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +0530251 } else {
252 errorInfo = LEAFREF_LINKER_ERROR;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530253 }
254 DataModelException dataModelException =
255 new DataModelException(errorInfo);
256 dataModelException.setLine(getLineNumber());
257 dataModelException.setCharPosition(getCharPosition());
258 throw dataModelException;
259 }
260 break;
261 }
262 default: {
263 throw new DataModelException("Data Model Exception: Unsupported, linker state");
264 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530265
266 }
267
268 } else {
janani b0e4e8ae2016-07-13 21:06:41 +0530269 throw new DataModelException(
Shankara-Huawei234cd092016-07-14 11:35:34 +0530270 "Data Model Exception: Entity to resolved is other than type/uses/if-feature" +
271 "/leafref/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530272 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530273 }
274
275 }
276
277 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530278 * Adds the leafref/identityref type to the type, which has derived type referring to
279 * typedef with leafref/identityref type.
janani b0e4e8ae2016-07-13 21:06:41 +0530280 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530281 private void addDerivedRefTypeToRefTypeResolutionList()
282 throws DataModelException {
janani b0e4e8ae2016-07-13 21:06:41 +0530283
284 YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
285
286 // If holder is typedef return.
287 if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
288 return;
289 }
290
291 // If entity is not type return.
292 if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
293 return;
294 }
295
296 YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
297
298 // If type is not resolved return.
299 if (yangType.getResolvableStatus() != RESOLVED) {
300 return;
301 }
302
303 YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
304
Vidyashree Ramab3670472016-08-06 15:49:56 +0530305 // If the derived types referred type is not leafref/identityref return
Shankara-Huawei234cd092016-07-14 11:35:34 +0530306 if ((derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) &&
307 (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.IDENTITYREF)) {
janani b0e4e8ae2016-07-13 21:06:41 +0530308 return;
309 }
310
311 T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
312
313 while (extendedInfo instanceof YangDerivedInfo) {
314 YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
315 extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
316 .getDataTypeExtendedInfo();
317 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530318
janani b0e4e8ae2016-07-13 21:06:41 +0530319 /*
Shankara-Huawei234cd092016-07-14 11:35:34 +0530320 * Backup the derived types leafref/identityref info, delete all the info in current type,
321 * but for resolution status as resolved. Copy the backed up leafref/identityref to types extended info,
322 * create a leafref/identityref resolution info using the current resolution info and
323 * add to leafref/identityref resolution list.
janani b0e4e8ae2016-07-13 21:06:41 +0530324 */
Shankara-Huawei234cd092016-07-14 11:35:34 +0530325 if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.LEAFREF) {
326 YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
327 yangType.resetYangType();
janani b0e4e8ae2016-07-13 21:06:41 +0530328
Shankara-Huawei234cd092016-07-14 11:35:34 +0530329 yangType.setResolvableStatus(RESOLVED);
330 yangType.setDataType(YangDataTypes.LEAFREF);
331 yangType.setDataTypeName(LEAFREF);
332 yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
333 leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
janani bebb143d2016-07-14 19:35:22 +0530334 leafRefInTypeDef.setParentNodeOfLeafref(potentialAncestorWithReferredNode);
janani b0e4e8ae2016-07-13 21:06:41 +0530335
Shankara-Huawei234cd092016-07-14 11:35:34 +0530336 // Add resolution information to the list.
337 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
janani bebb143d2016-07-14 19:35:22 +0530338 potentialAncestorWithReferredNode,
339 getLineNumber(), getCharPosition());
Shankara-Huawei234cd092016-07-14 11:35:34 +0530340 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani bebb143d2016-07-14 19:35:22 +0530341 ResolvableType.YANG_LEAFREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530342 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
343
344 } else if (derivedInfo.getEffectiveBuiltInType() == YangDataTypes.IDENTITYREF) {
345
346 YangIdentityRef identityRefInTypeDef = (YangIdentityRef) extendedInfo;
347 yangType.resetYangType();
348
349 yangType.setResolvableStatus(RESOLVED);
350 yangType.setDataType(YangDataTypes.IDENTITYREF);
351 yangType.setDataTypeName(IDENTITYREF);
352 yangType.setDataTypeExtendedInfo(identityRefInTypeDef);
353 identityRefInTypeDef.setResolvableStatus(UNRESOLVED);
354
355 // Add resolution information to the list.
356 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(identityRefInTypeDef,
janani bebb143d2016-07-14 19:35:22 +0530357 potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
Shankara-Huawei234cd092016-07-14 11:35:34 +0530358 getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
janani bebb143d2016-07-14 19:35:22 +0530359 ResolvableType.YANG_IDENTITYREF);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530360 getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_IDENTITYREF);
361 }
janani b0e4e8ae2016-07-13 21:06:41 +0530362 }
363
364 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530365 * Resolves the current entity in the stack.
366 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530367 private void resolveTopOfStack(YangLinkingPhase linkingPhase)
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530368 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530369 List<T> entityToResolve = (List<T>) ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
370 if (entityToResolve != null && !entityToResolve.isEmpty()) {
371 Iterator<T> entityToResolveIterator = entityToResolve.listIterator();
372 while (entityToResolveIterator.hasNext()) {
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530373 addUnresolvedEntitiesToResolutionList(entityToResolveIterator.next());
janani bebb143d2016-07-14 19:35:22 +0530374 }
375 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530376 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
377 && ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
janani b0e4e8ae2016-07-13 21:06:41 +0530378 // Sets the resolution status in inside the type/uses/if-feature/leafref.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530379 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
380 }
381 }
382
383 /**
janani bebb143d2016-07-14 19:35:22 +0530384 * Adds the unresolved entities to the resolution list.
385 *
386 * @param entityToResolve entity to resolve
387 * @throws DataModelException a violation of data model rules
388 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530389 private void addUnresolvedEntitiesToResolutionList(T entityToResolve)
390 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +0530391 if (entityToResolve instanceof YangEntityToResolveInfoImpl) {
392 YangEntityToResolveInfoImpl entityToResolveInfo = (YangEntityToResolveInfoImpl) entityToResolve;
393 if (entityToResolveInfo.getEntityToResolve() instanceof YangLeafRef) {
394 YangLeafRef leafref = (YangLeafRef) entityToResolveInfo.getEntityToResolve();
395 YangNode parentNodeOfLeafref = entityToResolveInfo.getHolderOfEntityToResolve();
396 leafref.setParentNodeOfLeafref(parentNodeOfLeafref);
397 if (leafref.getResolvableStatus() == UNRESOLVED) {
398 leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
399 }
janani bebb143d2016-07-14 19:35:22 +0530400 }
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530401
402 // Add resolution information to the list.
403 YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(
404 entityToResolveInfo.getEntityToResolve(), entityToResolveInfo.getHolderOfEntityToResolve(),
405 entityToResolveInfo.getLineNumber(), entityToResolveInfo.getCharPosition());
406 addResolutionInfo(resolutionInfoImpl);
janani bebb143d2016-07-14 19:35:22 +0530407 }
408 }
409
410 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530411 * Resolves linking for a node child and siblings.
412 *
413 * @throws DataModelException data model error
414 */
415 private void linkTopOfStackReferenceUpdateStack()
416 throws DataModelException {
417
janani bebb143d2016-07-14 19:35:22 +0530418 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
419 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
420 return;
421 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530422 /*
423 * Check if self file reference is there, this will not check for the
424 * scenario when prefix is not present and type/uses is present in
425 * sub-module from include list.
426 */
427 if (!isCandidateForSelfFileReference()) {
428 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
429 return;
430 }
431
432 /**
433 * Try to resolve the top of the stack and update partial resolved stack
434 * if there is recursive references
435 */
436 YangNode potentialAncestorWithReferredNode = getPartialResolvedStack().peek()
437 .getHolderOfEntityToResolve();
438
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530439 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
440 resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
441 return;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530442 } else if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
443 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
444 resolveSelfFileLinkingForBaseAndIdentityref();
445 return;
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530446 } else {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530447
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530448 YangType type = null;
449 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
450 type = (YangType) getCurrentEntityToResolveFromStack();
451 }
452
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530453 /**
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();
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530468
469 if (type != null && potentialAncestorWithReferredNode != null) {
470 if (potentialAncestorWithReferredNode.getParent() == null) {
471 type.setTypeNotResolvedTillRootNode(true);
472 }
473 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530474 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530475 }
476
477 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530478 * 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 +0530479 * resolution via include list.
480 */
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530481 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530482 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
483 }
484 }
485
486 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530487 * Resolves self file linking for base/identityref.
488 *
489 * @throws DataModelException a violation of data model rules
490 */
491 private void resolveSelfFileLinkingForBaseAndIdentityref()
492 throws DataModelException {
493
494 boolean referredIdentityFound = false;
495 String nodeName = null;
496
497 if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
janani bebb143d2016-07-14 19:35:22 +0530498 nodeName = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName();
Shankara-Huawei234cd092016-07-14 11:35:34 +0530499 }
500
501 if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
502 nodeName = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName();
503 }
504
505 if (getCurReferenceResolver() instanceof YangModule) {
506 YangModule rootNode = (YangModule) getCurReferenceResolver();
507 // Sends list of nodes for finding the target identity.
508 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
509 } else if (getCurReferenceResolver() instanceof YangSubModule) {
510 YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
511 // Sends list of nodes for finding the target identity.
512 referredIdentityFound = isIdentityReferenceFound(nodeName, rootNode);
513 }
514
515 if (referredIdentityFound) {
516 return;
517 }
518
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530519 /*
520 * In case prefix is not present or it's self prefix it's a candidate for inter-file
521 * resolution via include list.
522 */
523 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530524 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
525 }
526 }
527
528 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530529 * Returns the root parent with respect to the ancestor count from leafref.
530 *
531 * @param ancestorCount count of node where parent node can be reached
532 * @param currentParent current parent node
533 * @return root node
534 * @throws DataModelException a violation of data model rules
535 */
536 private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
537 throws DataModelException {
538
539 int currentParentCount = 1;
540 while (currentParentCount < ancestorCount) {
541 if (currentParent.getParent() == null) {
Bharat saraswale3175d32016-08-31 17:50:11 +0530542 throw new DataModelException("YANG file error: The target node of leafref is invalid."
543 + currentParent.getName() + " in " +
544 currentParent.getLineNumber() + " at " +
545 currentParent.getCharPosition()
546 + " in " + currentParent.getFileName() + "\"");
janani b0e4e8ae2016-07-13 21:06:41 +0530547 }
548 currentParent = currentParent.getParent();
549 currentParentCount = currentParentCount + 1;
550 }
551 return currentParent;
552 }
553
554 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530555 * Resolves self file linking for if-feature.
556 *
557 * @param potentialAncestorWithReferredNode if-feature holder node
558 * @throws DataModelException DataModelException a violation of data model
559 * rules
560 */
561 private void resolveSelfFileLinkingForIfFeature(YangNode potentialAncestorWithReferredNode)
562 throws DataModelException {
563
564 YangFeatureHolder featureHolder = getFeatureHolder(potentialAncestorWithReferredNode);
565 YangNode potentialReferredNode = (YangNode) featureHolder;
566 if (isReferredNode(potentialReferredNode)) {
567
568 // Adds reference link of entity to the node under resolution.
569 addReferredEntityLink(potentialReferredNode, LINKED);
570
571 /**
572 * resolve the reference and update the partial resolution stack
573 * with any further recursive references
574 */
575 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
576 return;
577 }
578
579 /*
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530580 * 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 +0530581 * resolution via include list.
582 */
Gaurav Agrawal8a966b92016-08-20 00:07:27 +0530583 if (getRefPrefix() == null || getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530584 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
585 }
586 }
587
janani b0e4e8ae2016-07-13 21:06:41 +0530588 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530589 * Returns the status of the referred identity found for base/identityref.
590 *
janani bebb143d2016-07-14 19:35:22 +0530591 * @param nodeName the name of the base nodeidentifier/identityref nodeidentifier
Shankara-Huawei234cd092016-07-14 11:35:34 +0530592 * @param ancestorWithTheReferredNode the parent node of base/identityref
593 * @return status of referred base/identityref
594 * @throws DataModelException a violation of data model rules
595 */
596 private boolean isIdentityReferenceFound(String nodeName, YangNode ancestorWithTheReferredNode)
597 throws DataModelException {
598
599 // When child is not present return.
600 if (ancestorWithTheReferredNode.getChild() == null) {
601 return false;
602 }
603
604 ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
605
606 // Checks all the siblings under the node and returns the matched node.
607 YangNode nodeFound = isReferredNodeInSiblingProcessedForIdentity(ancestorWithTheReferredNode, nodeName);
608
609 if (nodeFound != null) {
610 // Adds reference link of entity to the node under resolution.
611 addReferredEntityLink(nodeFound, LINKED);
612
613 /**
614 * resolve the reference and update the partial resolution stack with any further recursive references
615 */
616 addUnresolvedRecursiveReferenceToStack(nodeFound);
617 return true;
618 }
619
620 return false;
621 }
622
623 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530624 * Adds the unresolved constructs to stack which has to be resolved for leafref.
625 *
janani bebb143d2016-07-14 19:35:22 +0530626 * @param yangleafOrLeafList YANG leaf or leaf list which holds the type
janani b0e4e8ae2016-07-13 21:06:41 +0530627 * @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
628 */
629 private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
630
631 YangType referredTypeInLeafOrLeafList;
632 if (yangleafOrLeafList instanceof YangLeaf) {
633 YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
634 referredTypeInLeafOrLeafList = leaf.getDataType();
635 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
636 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
637 unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
638 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
639 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
640 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
641 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
642 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
643 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
644 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
645 }
646 } else {
647 YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
648 referredTypeInLeafOrLeafList = leafList.getDataType();
649 if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
650 YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
651 unResolvedEntityInfo
652 .setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
653 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
654 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
655 } else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
656 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
657 unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
658 unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
659 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
660 }
661 }
662 }
663
664 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530665 * Returns feature holder(module/sub-module node) .
666 *
667 * @param potentialAncestorWithReferredNode if-feature holder node
668 */
669 private YangFeatureHolder getFeatureHolder(YangNode potentialAncestorWithReferredNode) {
670 while (potentialAncestorWithReferredNode != null) {
671 if (potentialAncestorWithReferredNode instanceof YangFeatureHolder) {
672 return (YangFeatureHolder) potentialAncestorWithReferredNode;
673 }
674 potentialAncestorWithReferredNode = potentialAncestorWithReferredNode.getParent();
675 }
676 return null;
677 }
678
679 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530680 * Checks if the reference in self file or in external file.
681 *
682 * @return true if self file reference, false otherwise
683 * @throws DataModelException a violation of data model rules
684 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +0530685 private boolean isCandidateForSelfFileReference()
686 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530687 String prefix = getRefPrefix();
688 return prefix == null || prefix.contentEquals(getCurReferenceResolver().getPrefix());
689 }
690
691 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530692 * Checks for the referred parent node for the leafref path.
693 *
694 * @param potentialReferredNode potential referred node
695 * @return the reffered parent node of leaf/leaf-list
696 * @throws DataModelException data model errors
697 */
698 private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
699 throws DataModelException {
700
701 while (potentialReferredNode != null) {
702 if (potentialReferredNode instanceof YangInput) {
703 if (referredNodeName.equalsIgnoreCase(INPUT)) {
704 return potentialReferredNode;
705 }
706 } else if (potentialReferredNode instanceof YangOutput) {
707 if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
708 return potentialReferredNode;
709 }
710 }
711 // Check if the potential referred node is the actual referred node
712 if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
713 if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
714 if (potentialReferredNode.getParent() instanceof YangRpc) {
715 potentialReferredNode = potentialReferredNode.getNextSibling();
716 } else {
Bharat saraswale3175d32016-08-31 17:50:11 +0530717 throw new DataModelException("YANG file error: The target node of leafref is invalid. "
718 + potentialReferredNode.getName() + " in " +
719 potentialReferredNode.getLineNumber() + " at " +
720 potentialReferredNode.getCharPosition()
721 + " in " + potentialReferredNode.getFileName() + "\"");
janani b0e4e8ae2016-07-13 21:06:41 +0530722 }
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,
Bharat saraswal2da23bf2016-08-25 15:28:39 +0530739 String referredNodeName)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530740 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 {
Bharat saraswale3175d32016-08-31 17:50:11 +0530772 throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref "
773 + currentReferredNode.getName() + " in " +
774 currentReferredNode.getLineNumber() + " at " +
775 currentReferredNode.getCharPosition()
776 + " in " + currentReferredNode.getFileName() + "\"");
janani b0e4e8ae2016-07-13 21:06:41 +0530777 }
778 }
779
780 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +0530781 * Checks if the current reference node name and the name in the base/identityref base are equal.
782 *
janani bebb143d2016-07-14 19:35:22 +0530783 * @param currentReferredNode the node where the reference is pointed
Shankara-Huawei234cd092016-07-14 11:35:34 +0530784 * @param nameOfIdentityRefBase name of the base in the base/identityref base
785 * @return status of the match between the name
786 * @throws DataModelException a violation of data model rules
787 */
788 private boolean isReferredNodeForIdentity(YangNode currentReferredNode, String nameOfIdentityRefBase)
789 throws DataModelException {
790
791 if ((getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) ||
792 (getCurrentEntityToResolveFromStack() instanceof YangBase)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +0530793
794 //Check if name of node name matches with the current reference node.
Shankara-Huawei234cd092016-07-14 11:35:34 +0530795 return currentReferredNode.getName().contentEquals(nameOfIdentityRefBase);
796 } else {
Bharat saraswale3175d32016-08-31 17:50:11 +0530797 throw new DataModelException("Data Model Exception: Entity to resolved is other than identityref"
798 + currentReferredNode.getName() + " in " +
799 currentReferredNode.getLineNumber() + " at " +
800 currentReferredNode.getCharPosition()
801 + " in " + currentReferredNode.getFileName() + "\"");
Shankara-Huawei234cd092016-07-14 11:35:34 +0530802 }
803 }
804
805 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530806 * Checks for the referred node defined in a ancestor scope.
807 *
808 * @param potentialReferredNode potential referred node
809 * @return status of resolution and updating the partial resolved stack with
810 * the any recursive references
janani b0e4e8ae2016-07-13 21:06:41 +0530811 * @throws DataModelException a violation of data model rules
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530812 */
813 private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
814 throws DataModelException {
815 while (potentialReferredNode != null) {
816
817 // Check if the potential referred node is the actual referred node
818 if (isReferredNode(potentialReferredNode)) {
819
820 // Adds reference link of entity to the node under resolution.
821 addReferredEntityLink(potentialReferredNode, LINKED);
822
823 /**
824 * resolve the reference and update the partial resolution stack
825 * with any further recursive references
826 */
827 addUnresolvedRecursiveReferenceToStack(potentialReferredNode);
828
829 /*
830 * return true, since the reference is linked and any recursive
831 * unresolved references is added to the stack
832 */
833 return true;
834 }
835
836 potentialReferredNode = potentialReferredNode.getNextSibling();
837 }
838 return false;
839 }
840
841 /**
842 * Checks if the potential referred node is the actual referred node.
843 *
844 * @param potentialReferredNode typedef/grouping node
845 * @return true if node is of resolve type otherwise false
846 * @throws DataModelException a violation of data model rules
847 */
848 private boolean isReferredNode(YangNode potentialReferredNode)
849 throws DataModelException {
850 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
851 if (potentialReferredNode instanceof YangTypeDef) {
852 /*
853 * Check if name of node name matches with the entity being
854 * resolved
855 */
856 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
857 }
858 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
859 if (potentialReferredNode instanceof YangGrouping) {
860 /*
861 * Check if name of node name matches with the entity being
862 * resolved
863 */
864 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
865 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530866 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
867 if (potentialReferredNode instanceof YangFeatureHolder) {
868 /*
869 * Check if name of node name matches with the entity being
870 * resolved
871 */
872 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
873 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530874 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
875 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
876 if (potentialReferredNode instanceof YangIdentity) {
877 /*
878 * Check if name of node name matches with the entity being
879 * resolved
880 */
881 return isNodeNameSameAsResolutionInfoName(potentialReferredNode);
882 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530883 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530884 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/" +
Bharat saraswale3175d32016-08-31 17:50:11 +0530885 "uses/base/identityref"
886 + potentialReferredNode.getName() + " in " +
887 potentialReferredNode.getLineNumber() + " at " +
888 potentialReferredNode.getCharPosition()
889 + " in " + potentialReferredNode.getFileName() + "\"");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530890 }
891 return false;
892 }
893
894 /**
895 * Checks if node name is same as name in resolution info, i.e. name of
896 * typedef/grouping is same as name of type/uses.
897 *
898 * @param node typedef/grouping node
899 * @return true if node name is same as name in resolution info, otherwise
900 * false
901 * @throws DataModelException a violation of data model rules
902 */
903
904 private boolean isNodeNameSameAsResolutionInfoName(YangNode node)
905 throws DataModelException {
906 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
907 if (node.getName().contentEquals(
908 ((YangType<?>) getCurrentEntityToResolveFromStack())
909 .getDataTypeName())) {
910 return true;
911 }
912 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
913 if (node.getName().contentEquals(
914 ((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
915 return true;
916 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530917 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
918 return isFeatureDefinedInNode(node);
Shankara-Huawei234cd092016-07-14 11:35:34 +0530919 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
920 if (node.getName().contentEquals(
921 ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
922 return true;
923 }
924 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
925 if (node.getName().contentEquals(
926 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getName())) {
927 return true;
928 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530929 } else {
Bharat saraswale3175d32016-08-31 17:50:11 +0530930 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses "
931 + node.getName() + " in " +
932 node.getLineNumber() + " at " +
933 node.getCharPosition()
934 + " in " + node.getFileName() + "\"");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530935 }
936 return false;
937 }
938
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530939 private boolean isFeatureDefinedInNode(YangNode node)
940 throws DataModelException {
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530941 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
942 List<YangFeature> featureList = ((YangFeatureHolder) node).getFeatureList();
943 if (featureList != null && !featureList.isEmpty()) {
944 Iterator<YangFeature> iterator = featureList.iterator();
945 while (iterator.hasNext()) {
946 YangFeature feature = iterator.next();
947 if (ifFeature.getName().equals(feature.getName())) {
948 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
949 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeatureHolder(node);
950 return true;
951 }
952 }
953 }
954 return false;
955 }
956
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530957 /**
958 * Adds reference of grouping/typedef in uses/type.
959 *
960 * @param referredNode grouping/typedef node being referred
961 * @param linkedStatus linked status if success.
962 * @throws DataModelException a violation of data model rules
963 */
964 private void addReferredEntityLink(YangNode referredNode, ResolvableStatus linkedStatus)
965 throws DataModelException {
966 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +0530967 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
968 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530969 derivedInfo.setReferredTypeDef((YangTypeDef) referredNode);
970 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
971 ((YangUses) getCurrentEntityToResolveFromStack())
972 .setRefGroup((YangGrouping) referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +0530973 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
974 // do nothing , referred node is already set
janani b0e4e8ae2016-07-13 21:06:41 +0530975 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
976 // do nothing , referred node is already set
Shankara-Huawei234cd092016-07-14 11:35:34 +0530977 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
978 ((YangBase) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
979 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
980 ((YangIdentityRef) getCurrentEntityToResolveFromStack()).setReferredIdentity((YangIdentity) referredNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530981 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530982 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
Bharat saraswale3175d32016-08-31 17:50:11 +0530983 "/uses/base/identityref"
984 + referredNode.getName() + " in " +
985 referredNode.getLineNumber() + " at " +
986 referredNode.getCharPosition()
987 + " in " + referredNode.getFileName() + "\"");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530988 }
989
990 // Sets the resolution status in inside the type/uses.
991 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(linkedStatus);
992 }
993
994 /**
995 * Checks if type/grouping has further reference to typedef/ unresolved
996 * uses. Add it to the partial resolve stack and return the status of
997 * addition to stack.
998 *
999 * @param referredNode grouping/typedef node
1000 * @throws DataModelException a violation of data model rules
1001 */
1002 private void addUnresolvedRecursiveReferenceToStack(YangNode referredNode)
1003 throws DataModelException {
1004 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301005
1006 //Checks if typedef type is derived
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301007 if (((YangTypeDef) referredNode).getTypeDefBaseType().getDataType() == YangDataTypes.DERIVED) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301008
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301009 YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301010 unResolvedEntityInfo.setEntityToResolve(((YangTypeDef) referredNode)
1011 .getTypeDefBaseType());
1012 unResolvedEntityInfo.setHolderOfEntityToResolve(referredNode);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301013 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301014 }
1015
1016 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1017 /*
1018 * Search if the grouping has any un resolved uses child, if so
1019 * return true, else return false.
1020 */
1021 addUnResolvedUsesToStack(referredNode);
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301022 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1023 addUnResolvedIfFeatureToStack(referredNode);
janani b0e4e8ae2016-07-13 21:06:41 +05301024 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1025 // do nothing , referred node is already set
Bharat saraswale3175d32016-08-31 17:50:11 +05301026 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses "
1027 + referredNode.getName() + " in " +
1028 referredNode.getLineNumber() + " at " +
1029 referredNode.getCharPosition()
1030 + " in " + referredNode.getFileName() + "\"");
Shankara-Huawei234cd092016-07-14 11:35:34 +05301031 } else if ((getCurrentEntityToResolveFromStack() instanceof YangBase) ||
1032 (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef)) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301033
1034 //Search if the identity has any un resolved base, if so return true, else return false.
Shankara-Huawei234cd092016-07-14 11:35:34 +05301035 addUnResolvedBaseToStack(referredNode);
1036 } else {
1037 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses/" +
Bharat saraswale3175d32016-08-31 17:50:11 +05301038 "base/identityref " + referredNode.getName() + " in " +
1039 referredNode.getLineNumber() + " at " +
1040 referredNode.getCharPosition()
1041 + " in " + referredNode.getFileName() + "\"");
1042
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301043 }
1044 }
1045
1046 /**
1047 * Returns if there is any unresolved uses in grouping.
1048 *
1049 * @param node grouping/typedef node
1050 */
1051 private void addUnResolvedUsesToStack(YangNode node) {
1052
Vidyashree Ramab3670472016-08-06 15:49:56 +05301053 //Search the grouping node's children for presence of uses node.
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301054 TraversalType curTraversal = ROOT;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301055 YangNode curNode = node.getChild();
1056 while (curNode != null) {
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301057 if (curNode.getName().equals(node.getName())) {
1058 // if we have traversed all the child nodes, then exit from loop
1059 return;
1060 }
1061
1062 // if child nodes has uses, then add it to resolution stack
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301063 if (curNode instanceof YangUses) {
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301064 YangEntityToResolveInfoImpl<YangUses> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301065 unResolvedEntityInfo.setEntityToResolve((YangUses) curNode);
1066 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301067 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301068 }
Vidyashree Rama72719fa2016-07-15 14:06:56 +05301069
1070 // Traversing all the child nodes of grouping
1071 if (curTraversal != PARENT && curNode.getChild() != null) {
1072 curTraversal = CHILD;
1073 curNode = curNode.getChild();
1074 } else if (curNode.getNextSibling() != null) {
1075 curTraversal = SIBILING;
1076 curNode = curNode.getNextSibling();
1077 } else {
1078 curTraversal = PARENT;
1079 curNode = curNode.getParent();
1080 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301081 }
1082 }
1083
1084 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301085 * Returns if there is any unresolved if-feature in feature.
1086 *
1087 * @param node module/submodule node
1088 */
1089 private void addUnResolvedIfFeatureToStack(YangNode node) {
1090 YangFeature refFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeature();
1091 List<YangIfFeature> ifFeatureList = refFeature.getIfFeatureList();
1092 if (ifFeatureList != null && !ifFeatureList.isEmpty()) {
1093 Iterator<YangIfFeature> ifFeatureIterator = ifFeatureList.iterator();
1094 while (ifFeatureIterator.hasNext()) {
1095 YangIfFeature ifFeature = ifFeatureIterator.next();
1096 YangEntityToResolveInfo<YangIfFeature> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1097 unResolvedEntityInfo.setEntityToResolve(ifFeature);
1098 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1099 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1100 }
1101 }
1102 }
1103
1104 /**
Shankara-Huawei234cd092016-07-14 11:35:34 +05301105 * Returns if there is any unresolved base in identity.
1106 *
1107 * @param node module/submodule node
1108 */
1109 private void addUnResolvedBaseToStack(YangNode node) {
1110
1111 YangIdentity curNode = (YangIdentity) node;
1112 if (curNode.getBaseNode() != null) {
1113 if (curNode.getBaseNode().getResolvableStatus() != RESOLVED) {
1114 YangEntityToResolveInfoImpl<YangBase> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
1115 unResolvedEntityInfo.setEntityToResolve(curNode.getBaseNode());
1116 unResolvedEntityInfo.setHolderOfEntityToResolve(node);
1117 addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
1118
1119 }
1120 }
1121 }
1122
1123
1124 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301125 * Returns stack of YANG type with partially resolved YANG construct
1126 * hierarchy.
1127 *
1128 * @return partial resolved YANG construct stack
1129 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301130 private Stack<YangEntityToResolveInfoImpl<T>> getPartialResolvedStack() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301131 return partialResolvedStack;
1132 }
1133
1134 /**
1135 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1136 *
1137 * @param partialResolvedStack partial resolved YANG construct stack
1138 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301139 private void setPartialResolvedStack(Stack<YangEntityToResolveInfoImpl<T>> partialResolvedStack) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301140 this.partialResolvedStack = partialResolvedStack;
1141 }
1142
1143 /**
1144 * Sets stack of YANG type with partially resolved YANG construct hierarchy.
1145 *
1146 * @param partialResolvedInfo partial resolved YANG construct stack
1147 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301148 private void addInPartialResolvedStack(YangEntityToResolveInfoImpl<T> partialResolvedInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301149 getPartialResolvedStack().push(partialResolvedInfo);
1150 }
1151
1152 /**
1153 * Retrieves the next entity in the stack that needs to be resolved. It is
1154 * assumed that the caller ensures that the stack is not empty.
1155 *
1156 * @return next entity in the stack that needs to be resolved
1157 */
1158 private T getCurrentEntityToResolveFromStack() {
1159 return getPartialResolvedStack().peek().getEntityToResolve();
1160 }
1161
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301162 @Override
1163 public YangEntityToResolveInfoImpl<T> getEntityToResolveInfo() {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301164 return entityToResolveInfo;
1165 }
1166
1167 /**
1168 * Sets information about the entity that needs to be resolved.
1169 *
1170 * @param entityToResolveInfo information about the entity that needs to be
1171 * resolved
1172 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301173 private void setEntityToResolveInfo(YangEntityToResolveInfoImpl<T> entityToResolveInfo) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301174 this.entityToResolveInfo = entityToResolveInfo;
1175 }
1176
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301177 /**
1178 * Returns current module/sub-module reference, will be used in inter-file/
1179 * inter-jar scenario to get the import/include list.
1180 *
1181 * @return current module/sub-module reference
1182 */
1183 private YangReferenceResolver getCurReferenceResolver() {
1184 return curReferenceResolver;
1185 }
1186
1187 /**
1188 * Sets current module/sub-module reference, will be used in inter-file/
1189 * inter-jar scenario to get the import/include list.
1190 *
1191 * @param curReferenceResolver current module/sub-module reference
1192 */
1193 private void setCurReferenceResolver(YangReferenceResolver curReferenceResolver) {
1194 this.curReferenceResolver = curReferenceResolver;
1195 }
1196
Gaurav Agrawal58b348e2016-06-07 14:00:26 +05301197 @Override
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301198 public void linkInterFile(YangReferenceResolver dataModelRootNode)
1199 throws DataModelException {
1200
1201 setCurReferenceResolver(dataModelRootNode);
1202
1203 // Current node to resolve, it can be a YANG type or YANG uses.
1204 T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
1205
1206 // Check if linking is already done
1207 if (entityToResolve instanceof Resolvable) {
1208 Resolvable resolvable = (Resolvable) entityToResolve;
1209 if (resolvable.getResolvableStatus() == RESOLVED) {
1210 return;
1211 }
1212 } else {
1213 throw new DataModelException("Data Model Exception: Entity to resolved is not Resolvable");
1214 }
1215
janani bebb143d2016-07-14 19:35:22 +05301216 if (entityToResolve instanceof YangXPathResolver && !(entityToResolve instanceof YangLeafRef)) {
Bharat saraswald14cbe82016-07-14 13:26:18 +05301217 //Process x-path linking.
janani bebb143d2016-07-14 19:35:22 +05301218 processXPathLinking(entityToResolve, dataModelRootNode);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301219
Bharat saraswald14cbe82016-07-14 13:26:18 +05301220 } else {
janani b0e4e8ae2016-07-13 21:06:41 +05301221
Bharat saraswald14cbe82016-07-14 13:26:18 +05301222 // Push the initial entity to resolve in stack.
1223 addInPartialResolvedStack(getEntityToResolveInfo());
1224
1225 // Inter file linking and resolution.
1226 linkInterFileAndResolve();
1227
1228 addDerivedRefTypeToRefTypeResolutionList();
1229 }
1230 }
1231
1232 /**
1233 * Process x-path linking for augment and leaf-ref.
1234 *
janani bebb143d2016-07-14 19:35:22 +05301235 * @param entityToResolve entity to resolve
1236 * @param root root node
Bharat saraswald14cbe82016-07-14 13:26:18 +05301237 */
janani bebb143d2016-07-14 19:35:22 +05301238 private void processXPathLinking(T entityToResolve,
Bharat saraswal2da23bf2016-08-25 15:28:39 +05301239 YangReferenceResolver root) {
janani bebb143d2016-07-14 19:35:22 +05301240
Bharat saraswald14cbe82016-07-14 13:26:18 +05301241 YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
janani bebb143d2016-07-14 19:35:22 +05301242
Bharat saraswald14cbe82016-07-14 13:26:18 +05301243 if (entityToResolve instanceof YangAugment) {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301244 YangNode targetNode = null;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301245 YangAugment augment = (YangAugment) entityToResolve;
1246 targetNode = xPathLinker.processAugmentXpathLinking(augment.getTargetNode(),
1247 (YangNode) root);
1248 if (targetNode != null) {
1249 if (targetNode instanceof YangAugmentableNode) {
1250 detectCollisionForAugmentedNode(targetNode, augment);
1251 ((YangAugmentableNode) targetNode).addAugmentation(augment);
1252 augment.setAugmentedNode(targetNode);
Vidyashree Ramab20ba9e2016-09-02 14:12:25 +05301253 setAugmentedFlagInAncestors(targetNode);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301254 Resolvable resolvable = (Resolvable) entityToResolve;
1255 resolvable.setResolvableStatus(RESOLVED);
1256 } else {
1257 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for "
Bharat saraswale3175d32016-08-31 17:50:11 +05301258 + augment.getName() + " for " + targetNode.getName() +
Mahesh Poojary Huawei230ab522016-09-02 16:47:19 +05301259 " in " + targetNode.getLineNumber()
Bharat saraswale3175d32016-08-31 17:50:11 +05301260 + " at " + targetNode.getCharPosition() +
1261 " in " + targetNode.getFileName());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301262 }
1263 } else {
Bharat saraswale3175d32016-08-31 17:50:11 +05301264 throw new LinkerException("Failed to link " + augment.getName() +
Mahesh Poojary Huawei230ab522016-09-02 16:47:19 +05301265 " in " + augment.getLineNumber()
Bharat saraswale3175d32016-08-31 17:50:11 +05301266 + " at " + augment.getCharPosition() +
1267 " in " + augment.getFileName());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301268 }
Vidyashree Ramab3670472016-08-06 15:49:56 +05301269 } else if (entityToResolve instanceof YangCompilerAnnotation) {
1270 YangNode targetNode;
1271 YangCompilerAnnotation ca = (YangCompilerAnnotation) entityToResolve;
1272
1273 targetNode = xPathLinker.processAugmentXpathLinking(ca.getAtomicPathList(),
1274 (YangNode) root);
1275 if (targetNode != null) {
1276 if (targetNode instanceof YangList) {
1277 ((YangList) targetNode).setCompilerAnnotation(
1278 (YangCompilerAnnotation) entityToResolve);
1279 Resolvable resolvable = (Resolvable) entityToResolve;
1280 resolvable.setResolvableStatus(RESOLVED);
1281 } else {
1282 throw new LinkerException("Invalid target node type " + targetNode.getNodeType() + " for compiler" +
Bharat saraswale3175d32016-08-31 17:50:11 +05301283 " annotation " + ca.getPath() + " in " + ca.getLineNumber() + " at "
1284 + ca.getCharPosition() + " in " + ca.getFileName());
Vidyashree Ramab3670472016-08-06 15:49:56 +05301285 }
1286 } else {
Bharat saraswale3175d32016-08-31 17:50:11 +05301287 throw new LinkerException("Failed to link compiler annotation " + ca.getPath()
1288 + " in " + ca.getLineNumber() + " at "
1289 + ca.getCharPosition() + " in " + ca.getFileName());
Vidyashree Ramab3670472016-08-06 15:49:56 +05301290 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301291 } else if (entityToResolve instanceof YangLeafRef) {
1292 YangLeafRef leafRef = (YangLeafRef) entityToResolve;
1293 Object target = xPathLinker.processLeafRefXpathLinking(leafRef.getAtomicPath(),
janani bebb143d2016-07-14 19:35:22 +05301294 (YangNode) root, leafRef);
Bharat saraswald14cbe82016-07-14 13:26:18 +05301295 if (target != null) {
Bharat saraswale3175d32016-08-31 17:50:11 +05301296 YangLeaf leaf;
1297 YangLeafList leafList;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301298 leafRef.setReferredLeafOrLeafList(target);
1299 if (target instanceof YangLeaf) {
1300 leaf = (YangLeaf) target;
janani bebb143d2016-07-14 19:35:22 +05301301 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1302 addUnResolvedLeafRefTypeToStack((T) leaf, getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301303 } else {
1304 leafList = (YangLeafList) target;
janani bebb143d2016-07-14 19:35:22 +05301305 leafRef.setResolvableStatus(INTER_FILE_LINKED);
1306 addUnResolvedLeafRefTypeToStack((T) leafList,
1307 getEntityToResolveInfo().getHolderOfEntityToResolve());
Bharat saraswald14cbe82016-07-14 13:26:18 +05301308 }
Bharat saraswald14cbe82016-07-14 13:26:18 +05301309 //TODO: add logic for leaf-ref for path predicates.
1310 } else {
janani bebb143d2016-07-14 19:35:22 +05301311 LinkerException linkerException = new LinkerException("YANG file error: Unable to find base " +
1312 "leaf/leaf-list for given leafref path "
Bharat saraswald14cbe82016-07-14 13:26:18 +05301313 + leafRef.getPath());
janani bebb143d2016-07-14 19:35:22 +05301314 linkerException.setCharPosition(leafRef.getCharPosition());
1315 linkerException.setLine(leafRef.getLineNumber());
Bharat saraswale3175d32016-08-31 17:50:11 +05301316 linkerException.setFileName(leafRef.getFileName());
janani bebb143d2016-07-14 19:35:22 +05301317 throw linkerException;
Bharat saraswald14cbe82016-07-14 13:26:18 +05301318 }
1319 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301320 }
1321
1322 /**
1323 * Returns the referenced prefix of entity under resolution.
1324 *
1325 * @return referenced prefix of entity under resolution
1326 * @throws DataModelException a violation in data model rule
1327 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301328 private String getRefPrefix()
1329 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301330 String refPrefix;
1331 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1332 refPrefix = ((YangType<?>) getCurrentEntityToResolveFromStack()).getPrefix();
1333 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1334 refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301335 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1336 refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301337 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1338 refPrefix = ((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getPrefix();
1339 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1340 refPrefix = ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getPrefix();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301341 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301342 throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
janani bebb143d2016-07-14 19:35:22 +05301343 "type/uses/base/identityref");
janani b0e4e8ae2016-07-13 21:06:41 +05301344 }
1345 return refPrefix;
1346 }
1347
1348 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301349 * Performs inter file linking and resolution.
1350 *
1351 * @throws DataModelException a violation in data model rule
1352 */
1353 private void linkInterFileAndResolve()
1354 throws DataModelException {
1355
1356 while (getPartialResolvedStack().size() != 0) {
1357
1358 // Current node to resolve, it can be a YANG type or YANG uses.
1359 T entityToResolve = getCurrentEntityToResolveFromStack();
1360 // Check if linking is already done
1361 if (entityToResolve instanceof Resolvable) {
1362
1363 Resolvable resolvable = (Resolvable) entityToResolve;
1364 switch (resolvable.getResolvableStatus()) {
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301365 case RESOLVED: {
1366 /*
1367 * If the entity is already resolved in the stack, then pop
1368 * it and continue with the remaining stack elements to
1369 * resolve
1370 */
1371 getPartialResolvedStack().pop();
1372 break;
1373 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301374
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301375 case INTER_FILE_LINKED: {
1376 /*
1377 * If the top of the stack is already linked then resolve
1378 * the references and pop the entity and continue with
1379 * remaining stack elements to resolve
1380 */
1381 resolveTopOfStack(INTER_FILE);
1382 getPartialResolvedStack().pop();
1383 break;
1384 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301385
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301386 case INTRA_FILE_RESOLVED: {
1387 /*
1388 * If the top of the stack is intra file resolved then check
1389 * if top of stack is linked, if not link it using
1390 * import/include list and push the linked referred entity
1391 * to the stack, otherwise only push it to the stack.
1392 */
1393 linkInterFileTopOfStackRefUpdateStack();
1394 break;
1395 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301396
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301397 case UNDEFINED: {
1398 /*
1399 * In case of if-feature resolution, if referred "feature" is not
1400 * defined then the resolvable status will be undefined.
1401 */
1402 getPartialResolvedStack().pop();
1403 break;
1404 }
1405
1406 default: {
1407 throw new DataModelException("Data Model Exception: Unsupported, linker state");
1408 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301409
1410 }
1411
1412 } else {
1413 throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
1414 }
1415
1416 }
1417
1418 }
1419
1420 /**
1421 * Links the top of the stack if it's inter-file and update stack.
1422 *
1423 * @throws DataModelException data model error
1424 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301425 private void linkInterFileTopOfStackRefUpdateStack()
1426 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301427
janani bebb143d2016-07-14 19:35:22 +05301428 if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1429 // When leafref path comes with relative path, it will be converted to absolute path.
1430 setAbsolutePathFromRelativePathInLeafref(getCurrentEntityToResolveFromStack());
1431 processXPathLinking(getCurrentEntityToResolveFromStack(), getCurReferenceResolver());
1432 return;
1433 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301434 /*
1435 * Obtain the referred node of top of stack entity under resolution
1436 */
1437 T referredNode = getRefNode();
1438
1439 /*
1440 * Check for null for scenario when it's not linked and inter-file
1441 * linking is required.
1442 */
1443 if (referredNode == null) {
1444
1445 /*
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301446 * Check if prefix is null or not, to identify whether to search in
1447 * import list or include list.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301448 */
Bharat saraswal5cd9e9c2016-05-26 23:48:38 +05301449 if (getRefPrefix() != null && !getRefPrefix().contentEquals(getCurReferenceResolver().getPrefix())) {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301450 if (resolveWithImport()) {
1451 return;
1452 }
1453 } else {
1454 if (resolveWithInclude()) {
1455 return;
1456 }
1457 }
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301458
1459 if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1460 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
1461 return;
1462 }
janani b0e4e8ae2016-07-13 21:06:41 +05301463 // If current entity is still not resolved, then
1464 // linking/resolution has failed.
1465 String errorInfo;
1466 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1467 errorInfo = TYPEDEF_LINKER_ERROR;
1468 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1469 errorInfo = GROUPING_LINKER_ERROR;
1470 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1471 errorInfo = FEATURE_LINKER_ERROR;
Shankara-Huawei234cd092016-07-14 11:35:34 +05301472 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1473 errorInfo = BASE_LINKER_ERROR;
1474 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1475 errorInfo = IDENTITYREF_LINKER_ERROR;
janani b0e4e8ae2016-07-13 21:06:41 +05301476 } else {
1477 errorInfo = LEAFREF_LINKER_ERROR;
1478 }
1479 DataModelException dataModelException = new DataModelException(errorInfo);
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301480 dataModelException.setLine(getLineNumber());
1481 dataModelException.setCharPosition(getCharPosition());
1482 throw dataModelException;
1483 } else {
janani bebb143d2016-07-14 19:35:22 +05301484 ((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
1485 addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
1486 }
1487 }
1488
1489 /**
1490 * Sets the leafref with absolute path from the relative path.
1491 *
1492 * @param resolutionInfo information about the YANG construct which has to be resolved
1493 * @throws DataModelException a violation of data model rules
1494 */
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301495 public void setAbsolutePathFromRelativePathInLeafref(T resolutionInfo)
1496 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301497 if (resolutionInfo instanceof YangLeafRef) {
1498
1499 YangNode parentOfLeafref = ((YangLeafRef) resolutionInfo).getParentNodeOfLeafref();
1500 YangLeafRef leafref = (YangLeafRef) resolutionInfo;
1501
1502 // Checks if the leafref has relative path in it.
1503 if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
1504 YangRelativePath relativePath = leafref.getRelativePath();
1505 List<YangAtomicPath> absoluteInRelative = relativePath.getAtomicPathList();
1506 int numberOfAncestors = relativePath.getAncestorNodeCount();
1507
1508 // Gets the root node from the ancestor count.
1509 T nodeOrAugmentList = getRootNodeWithAncestorCountForLeafref(numberOfAncestors, parentOfLeafref,
1510 leafref);
1511 if (nodeOrAugmentList instanceof YangNode) {
1512 String pathNameToBePrefixed = EMPTY_STRING;
1513 YangNode rootNode = (YangNode) nodeOrAugmentList;
1514 // Forms a new absolute path from the relative path
1515 while (!(rootNode instanceof YangReferenceResolver)) {
1516 pathNameToBePrefixed = rootNode.getName() + SLASH_FOR_STRING + pathNameToBePrefixed;
1517 rootNode = rootNode.getParent();
1518 if (rootNode == null) {
1519 throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
1520 }
1521 }
1522 fillAbsolutePathValuesInLeafref(leafref, pathNameToBePrefixed, absoluteInRelative);
1523 } else {
1524 List<String> listOfAugment = (List<String>) nodeOrAugmentList;
1525 Iterator<String> listOfAugmentIterator = listOfAugment.listIterator();
1526 String augment = EMPTY_STRING;
1527 while (listOfAugmentIterator.hasNext()) {
1528 augment = augment + SLASH_FOR_STRING + listOfAugmentIterator.next();
1529 }
1530 fillAbsolutePathValuesInLeafref(leafref, augment, absoluteInRelative);
janani b0e4e8ae2016-07-13 21:06:41 +05301531 }
janani b0e4e8ae2016-07-13 21:06:41 +05301532 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301533 }
1534 }
1535
1536 /**
janani bebb143d2016-07-14 19:35:22 +05301537 * Fills the absolute path values in the leafref from relative path.
1538 *
Bharat saraswal8beac342016-08-04 02:00:03 +05301539 * @param leafref instance of YANG leafref
1540 * @param pathNameToBePrefixed path name which has to be prefixed to relative path
1541 * @param atomicPathsInRelative atomic paths in relative
janani bebb143d2016-07-14 19:35:22 +05301542 * @throws DataModelException a violation of data model rules
1543 */
1544 private void fillAbsolutePathValuesInLeafref(YangLeafRef leafref, String pathNameToBePrefixed,
Bharat saraswal2da23bf2016-08-25 15:28:39 +05301545 List<YangAtomicPath> atomicPathsInRelative)
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +05301546 throws DataModelException {
janani bebb143d2016-07-14 19:35:22 +05301547
1548 leafref.setPathType(YangPathArgType.ABSOLUTE_PATH);
1549 String[] pathName = new String[0];
1550 if (pathNameToBePrefixed != EMPTY_STRING && pathNameToBePrefixed != null) {
1551 pathName = pathNameToBePrefixed.split(SLASH_FOR_STRING);
1552 }
1553 List<YangAtomicPath> finalListForAbsolute = new LinkedList<>();
1554 for (String value : pathName) {
1555 if (value != null && !value.isEmpty() && value != EMPTY_STRING) {
1556 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(value, YangConstructType.PATH_DATA);
1557 YangAtomicPath atomicPath = new YangAtomicPath();
1558 atomicPath.setNodeIdentifier(nodeIdentifier);
1559 finalListForAbsolute.add(atomicPath);
1560 }
1561 }
1562 if (atomicPathsInRelative != null && !atomicPathsInRelative.isEmpty()) {
1563 Iterator<YangAtomicPath> atomicPathIterator = atomicPathsInRelative.listIterator();
1564 while (atomicPathIterator.hasNext()) {
1565 YangAtomicPath yangAtomicPath = atomicPathIterator.next();
1566 finalListForAbsolute.add(yangAtomicPath);
1567 }
1568 leafref.setAtomicPath(finalListForAbsolute);
1569 } else {
1570 DataModelException dataModelException = new DataModelException("YANG file error: The target node, in the " +
1571 "leafref path " + leafref.getPath() + ", is invalid.");
1572 dataModelException.setCharPosition(leafref.getCharPosition());
1573 dataModelException.setLine(leafref.getLineNumber());
Bharat saraswale3175d32016-08-31 17:50:11 +05301574 dataModelException.setFileName(leafref.getFileName());
janani bebb143d2016-07-14 19:35:22 +05301575 throw dataModelException;
1576 }
1577 }
1578
1579 /**
1580 * Returns the root parent with respect to the ancestor count from leafref.
1581 *
1582 * @param ancestorCount count of node where parent node can be reached
1583 * @param currentParent current parent node
1584 * @param leafref instance of YANG leafref
1585 * @return node where the ancestor count stops or augment path name list
1586 * @throws DataModelException a violation of data model rules
1587 */
1588 private T getRootNodeWithAncestorCountForLeafref(int ancestorCount, YangNode currentParent, YangLeafRef leafref)
1589 throws DataModelException {
1590
1591 int currentParentCount = 1;
1592 currentParent = skipInvalidDataNodes(currentParent, leafref);
1593 if (currentParent instanceof YangAugment) {
1594 YangAugment augment = (YangAugment) currentParent;
1595 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1596 return (T) valueInAugment;
1597 } else {
1598 while (currentParentCount < ancestorCount) {
1599 YangNode currentSkippedParent = skipInvalidDataNodes(currentParent, leafref);
1600 if (currentSkippedParent == currentParent) {
1601 if (currentParent.getParent() == null) {
1602 throw new DataModelException("YANG file error: The target node, in the leafref path "
Bharat saraswale3175d32016-08-31 17:50:11 +05301603 + leafref.getPath() + ", is invalid."
1604 + " in " +
1605 leafref.getLineNumber() + " at " +
1606 leafref.getCharPosition()
1607 + " in " + leafref.getFileName() + "\"");
janani bebb143d2016-07-14 19:35:22 +05301608 }
1609 currentParent = currentParent.getParent();
1610 } else {
1611 currentParent = currentSkippedParent;
1612 continue;
1613 }
1614 currentParentCount = currentParentCount + 1;
1615 if (currentParent instanceof YangAugment) {
1616 YangAugment augment = (YangAugment) currentParent;
1617 List<String> valueInAugment = getPathWithAugment(augment, ancestorCount - currentParentCount);
1618 return (T) valueInAugment;
1619 }
1620 }
1621 }
1622 return (T) currentParent;
1623 }
1624
1625 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301626 * Finds and resolves with include list.
1627 *
1628 * @return true if resolved, false otherwise
1629 * @throws DataModelException a violation in data model rule
1630 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301631 private boolean resolveWithInclude()
1632 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301633 /*
1634 * Run through all the nodes in include list and search for referred
1635 * typedef/grouping at the root level.
1636 */
1637 for (YangInclude yangInclude : getCurReferenceResolver().getIncludeList()) {
1638 YangNode linkedNode = null;
1639 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1640 linkedNode = findRefTypedef(yangInclude.getIncludedNode());
1641 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1642 linkedNode = findRefGrouping(yangInclude.getIncludedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301643 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1644 linkedNode = findRefFeature(yangInclude.getIncludedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301645 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1646 linkedNode = findRefIdentity(yangInclude.getIncludedNode());
1647 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1648 linkedNode = findRefIdentityRef(yangInclude.getIncludedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301649 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301650
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301651 if (linkedNode != null) {
1652 // Add the link to external entity.
1653 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301654
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301655 // Add the type/uses of referred typedef/grouping to the stack.
1656 addUnresolvedRecursiveReferenceToStack(linkedNode);
1657 return true;
1658 }
1659 }
1660 // If referred node can't be found return false.
1661 return false;
1662 }
1663
1664 /**
1665 * Finds and resolves with import list.
1666 *
1667 * @return true if resolved, false otherwise
1668 * @throws DataModelException a violation in data model rule
1669 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301670 private boolean resolveWithImport()
1671 throws DataModelException {
Vidyashree Ramab3670472016-08-06 15:49:56 +05301672
1673 // Run through import list to find the referred typedef/grouping.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301674 for (YangImport yangImport : getCurReferenceResolver().getImportList()) {
1675 /*
1676 * Match the prefix attached to entity under resolution with the
1677 * imported/included module/sub-module's prefix. If found, search
1678 * for the referred typedef/grouping at the root level.
1679 */
1680 if (yangImport.getPrefixId().contentEquals(getRefPrefix())) {
1681 YangNode linkedNode = null;
1682 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
1683 linkedNode = findRefTypedef(yangImport.getImportedNode());
1684 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1685 linkedNode = findRefGrouping(yangImport.getImportedNode());
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301686 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1687 linkedNode = findRefFeature(yangImport.getImportedNode());
Shankara-Huawei234cd092016-07-14 11:35:34 +05301688 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1689 linkedNode = findRefIdentity(yangImport.getImportedNode());
1690 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1691 linkedNode = findRefIdentityRef(yangImport.getImportedNode());
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301692 }
1693 if (linkedNode != null) {
1694 // Add the link to external entity.
1695 addReferredEntityLink(linkedNode, INTER_FILE_LINKED);
Vidyashree Rama918f1622016-07-28 17:33:15 +05301696
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301697 // Add the type/uses of referred typedef/grouping to the
1698 // stack.
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301699 addUnresolvedRecursiveReferenceToStack(linkedNode);
1700 return true;
1701 }
1702 /*
1703 * If referred node can't be found at root level break for loop,
1704 * and return false.
1705 */
1706 break;
1707 }
1708 }
1709 // If referred node can't be found return false.
1710 return false;
1711 }
1712
1713 /**
1714 * Returns referred typedef/grouping node.
1715 *
1716 * @return referred typedef/grouping node
1717 * @throws DataModelException a violation in data model rule
1718 */
VinodKumarS-Huaweid81eccb2016-06-01 14:30:22 +05301719 private T getRefNode()
1720 throws DataModelException {
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301721 if (getCurrentEntityToResolveFromStack() instanceof YangType) {
Bharat saraswalc2d3be12016-06-16 00:29:12 +05301722 YangDerivedInfo<?> derivedInfo = (YangDerivedInfo<?>) ((YangType<?>) getCurrentEntityToResolveFromStack())
1723 .getDataTypeExtendedInfo();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301724 return (T) derivedInfo.getReferredTypeDef();
1725 } else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
1726 return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301727 } else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
1728 return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
janani b0e4e8ae2016-07-13 21:06:41 +05301729 } else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
1730 return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
Shankara-Huawei234cd092016-07-14 11:35:34 +05301731 } else if (getCurrentEntityToResolveFromStack() instanceof YangBase) {
1732 return (T) ((YangBase) getCurrentEntityToResolveFromStack()).getReferredIdentity();
1733 } else if (getCurrentEntityToResolveFromStack() instanceof YangIdentityRef) {
1734 return (T) ((YangIdentityRef) getCurrentEntityToResolveFromStack()).getReferredIdentity();
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301735 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301736 throw new DataModelException("Data Model Exception: Entity to resolved is other than type" +
janani bebb143d2016-07-14 19:35:22 +05301737 "/uses/base/identityref");
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301738 }
1739 }
1740
1741 /**
1742 * Finds the referred grouping node at the root level of imported/included node.
1743 *
1744 * @param refNode module/sub-module node
1745 * @return referred grouping
1746 */
1747 private YangNode findRefGrouping(YangNode refNode) {
1748 YangNode tmpNode = refNode.getChild();
1749 while (tmpNode != null) {
1750 if (tmpNode instanceof YangGrouping) {
1751 if (tmpNode.getName()
1752 .equals(((YangUses) getCurrentEntityToResolveFromStack()).getName())) {
1753 return tmpNode;
1754 }
1755 }
1756 tmpNode = tmpNode.getNextSibling();
1757 }
1758 return null;
1759 }
1760
1761 /**
Vidyashree Rama13b4c552016-06-20 15:12:43 +05301762 * Finds the referred feature node at the root level of imported/included node.
1763 *
1764 * @param refNode module/sub-module node
1765 * @return referred feature
1766 */
1767 private YangNode findRefFeature(YangNode refNode) {
1768 YangNodeIdentifier ifFeature = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getName();
1769 List<YangFeature> featureList = ((YangFeatureHolder) refNode).getFeatureList();
1770
1771 if (featureList != null && !featureList.isEmpty()) {
1772 Iterator<YangFeature> iterator = featureList.iterator();
1773 while (iterator.hasNext()) {
1774 YangFeature feature = iterator.next();
1775 if (ifFeature.getName().equals(feature.getName())) {
1776 ((YangIfFeature) getCurrentEntityToResolveFromStack()).setReferredFeature(feature);
1777 return refNode;
1778 }
1779 }
1780 }
1781 return null;
1782 }
1783
1784 /**
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301785 * Finds the referred typedef node at the root level of imported/included node.
1786 *
1787 * @param refNode module/sub-module node
1788 * @return referred typedef
1789 */
1790 private YangNode findRefTypedef(YangNode refNode) {
1791 YangNode tmpNode = refNode.getChild();
1792 while (tmpNode != null) {
1793 if (tmpNode instanceof YangTypeDef) {
1794 if (tmpNode.getName()
1795 .equals(((YangType) getCurrentEntityToResolveFromStack()).getDataTypeName())) {
1796 return tmpNode;
1797 }
1798 }
1799 tmpNode = tmpNode.getNextSibling();
1800 }
1801 return null;
1802 }
Shankara-Huawei234cd092016-07-14 11:35:34 +05301803
1804 /**
1805 * Finds the referred identity node at the root level of imported/included node.
1806 *
1807 * @param refNode module/sub-module node
1808 * @return referred identity
1809 */
1810 private YangNode findRefIdentity(YangNode refNode) {
1811 YangNode tmpNode = refNode.getChild();
1812 while (tmpNode != null) {
1813 if (tmpNode instanceof YangIdentity) {
1814 if (tmpNode.getName()
1815 .equals(((YangBase) getCurrentEntityToResolveFromStack()).getBaseIdentifier().getName())) {
1816 return tmpNode;
1817 }
1818 }
1819 tmpNode = tmpNode.getNextSibling();
1820 }
1821 return null;
1822 }
1823
1824 /**
1825 * Finds the referred identity node at the root level of imported/included node.
1826 *
1827 * @param refNode module/sub-module node
1828 * @return referred identity
1829 */
1830 private YangNode findRefIdentityRef(YangNode refNode) {
1831 YangNode tmpNode = refNode.getChild();
1832 while (tmpNode != null) {
1833 if (tmpNode instanceof YangIdentity) {
1834 if (tmpNode.getName()
1835 .equals(((YangIdentityRef) getCurrentEntityToResolveFromStack())
janani bebb143d2016-07-14 19:35:22 +05301836 .getBaseIdentity().getName())) {
Shankara-Huawei234cd092016-07-14 11:35:34 +05301837 return tmpNode;
1838 }
1839 }
1840 tmpNode = tmpNode.getNextSibling();
1841 }
1842 return null;
1843 }
Bharat saraswal2da23bf2016-08-25 15:28:39 +05301844
Vidyashree Ramab20ba9e2016-09-02 14:12:25 +05301845 /**
1846 * Sets descendant node augmented flag in ancestors.
1847 *
1848 * @param targetNode augmented YANG node
1849 */
1850 private void setAugmentedFlagInAncestors(YangNode targetNode) {
1851 targetNode = targetNode.getParent();
1852 while (targetNode != null) {
1853 targetNode.setDescendantNodeAugmented(true);
1854 targetNode = targetNode.getParent();
1855 }
1856 }
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +05301857}