janani b
Committed by Patrick Liu

[ONOS-4744] Leafref implementation and UT

Change-Id: I151797185e0bb1695c0640b667ae76ef87c4d4b0
Showing 73 changed files with 4871 additions and 135 deletions
......@@ -34,5 +34,10 @@ public enum ResolvableType {
/**
* Identifies the if-feature.
*/
YANG_IF_FEATURE
YANG_IF_FEATURE,
/**
* Identifies the leafref.
*/
YANG_LEAFREF
}
......
......@@ -24,6 +24,11 @@ import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import com.google.common.base.Strings;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processLengthRestriction;
import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processRangeRestriction;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypeUtils.isOfRangeRestrictedType;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BINARY;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BITS;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BOOLEAN;
......@@ -34,11 +39,6 @@ import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangData
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.LEAFREF;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.STRING;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UNION;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypeUtils.isOfRangeRestrictedType;
import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processLengthRestriction;
import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processRangeRestriction;
/**
* Represents the derived information.
......@@ -334,6 +334,9 @@ public class YangDerivedInfo<T>
return RESOLVED;
}
}
} else if (baseType.getDataType() == LEAFREF) {
setEffectiveBuiltInType(baseType.getDataType());
return RESOLVED;
} else {
setEffectiveBuiltInType(baseType.getDataType());
/*
......@@ -412,7 +415,6 @@ public class YangDerivedInfo<T>
}
}
}
/*
* Check if the data type is the one which can't be restricted, in this
* case check whether no self restrictions should be present.
......@@ -426,7 +428,6 @@ public class YangDerivedInfo<T>
throw new DataModelException("YANG file error: Restrictions can't be applied to a given type");
}
}
// Throw exception for unsupported types
throw new DataModelException("Linker error: Unable to process the derived type.");
}
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.datamodel;
import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
/*
* Reference:RFC 6020.
* The leafref type is used to reference a particular leaf instance in
* the data tree. The "path" substatement (Section 9.9.2) selects a set
* of leaf instances, and the leafref value space is the set of values
* of these leaf instances.
*/
/**
* Represents the leafref information.
*
* @param <T> YANG leafref info
*/
public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangIfFeatureHolder {
private static final long serialVersionUID = 286201644L;
/**
* YANG data type.
*/
private YangType effectiveDataType;
/**
* Referred leaf/leaf-list for the path specified in the leafref type.
*/
private T referredLeafOrLeafList;
/**
* Path of the leafref.
*/
private String path;
/**
* Leafref path type. Either absolute or relative path.
*/
private YangPathArgType pathType;
/**
* List of atomic paths in absolute Path.
*/
private List<YangAtomicPath> atomicPath;
/**
* YANG relative path.
*/
private YangRelativePath relativePath;
/**
* Status of resolution. If completely resolved enum value is "RESOLVED",
* if not enum value is "UNRESOLVED", in case reference of grouping/typedef/leafref
* is added to uses/type/leafref but it's not resolved value of enum should be
* "INTRA_FILE_RESOLVED".
*/
private ResolvableStatus resolvableStatus;
/**
* Require instance status in leafref type.
*/
private boolean requireInstance;
/**
* List of if-feature.
*/
private List<YangIfFeature> ifFeatureList;
/**
* Returns the status of the require instance in leafref.
*
* @return status of the require instance
*/
public boolean getRequireInstance() {
return requireInstance;
}
/**
* Sets the status of the require instance in leafref.
*
* @param requireInstance status of the require instance
*/
public void setRequireInstance(boolean requireInstance) {
this.requireInstance = requireInstance;
}
/**
* Returns the type of data.
*
* @return the data type
*/
public YangType getEffectiveDataType() {
return effectiveDataType;
}
/**
* Sets the type of data.
*
* @param effectiveDataType data type
*/
public void setEffectiveDataType(YangType effectiveDataType) {
this.effectiveDataType = effectiveDataType;
}
/**
* Returns the path of the leafref.
*
* @return path of the leafref
*/
public String getPath() {
return path;
}
/**
* Sets the path of the leafref.
*
* @param path leafref path
*/
public void setPath(String path) {
this.path = path;
}
/**
* Returns the type of path in the leafref.
*
* @return type of path
*/
public YangPathArgType getPathType() {
return pathType;
}
/**
* Sets the type of path in the leafref. It can be either absolute or relative type.
*
* @param pathType type of path
*/
public void setPathType(YangPathArgType pathType) {
this.pathType = pathType;
}
/**
* Returns the list of atomic path.
*
* @return list of atomic path
*/
public List<YangAtomicPath> getAtomicPath() {
return atomicPath;
}
/**
* Sets the list of atomic path.
*
* @param atomicPath list of atomic path.
*/
public void setAtomicPath(List<YangAtomicPath> atomicPath) {
this.atomicPath = atomicPath;
}
/**
* Returns the object of relative path.
*
* @return object of relative path
*/
public YangRelativePath getRelativePath() {
return relativePath;
}
/**
* Sets the object of relative path.
*
* @param relativePath object of relative path.
*/
public void setRelativePath(YangRelativePath relativePath) {
this.relativePath = relativePath;
}
/**
* Returns the object of referred leaf/leaf-list.
*
* @return object of referred leaf/leaf-list
*/
public T getReferredLeafOrLeafList() {
return referredLeafOrLeafList;
}
/**
* Sets the object of referred leaf/leaf-list.
*
* @param targetExtendedInfo object of referred leaf/leaf-list
*/
public void setReferredLeafOrLeafList(T targetExtendedInfo) {
this.referredLeafOrLeafList = targetExtendedInfo;
}
@Override
public List<YangIfFeature> getIfFeatureList() {
return ifFeatureList;
}
@Override
public void addIfFeatureList(YangIfFeature ifFeature) {
if (getIfFeatureList() == null) {
setIfFeatureList(new LinkedList<>());
}
getIfFeatureList().add(ifFeature);
}
@Override
public void setIfFeatureList(List<YangIfFeature> ifFeatureList) {
this.ifFeatureList = ifFeatureList;
}
@Override
public YangConstructType getYangConstructType() {
return YangConstructType.LEAFREF_DATA;
}
@Override
public void validateDataOnEntry() throws DataModelException {
// TODO auto-generated method stub, to be implemented by parser
}
@Override
public void validateDataOnExit() throws DataModelException {
// TODO auto-generated method stub, to be implemented by parser
}
@Override
public ResolvableStatus getResolvableStatus() {
return resolvableStatus;
}
@Override
public void setResolvableStatus(ResolvableStatus resolvableStatus) {
this.resolvableStatus = resolvableStatus;
}
@Override
public void resolve() throws DataModelException {
if (getReferredLeafOrLeafList() == null) {
throw new DataModelException("Linker Error: The leafref does not refer to any leaf/leaf-list.");
}
// Initiate the resolution
try {
setResolvableStatus(getResolution());
} catch (DataModelException e) {
throw new DataModelException(e.getMessage());
}
}
/**
* Returns the resolution status by getting the effective built-in type.
*
* @return status of resolution
* @throws DataModelException a violation of data model rules
*/
private ResolvableStatus getResolution() throws DataModelException {
if (getReferredLeafOrLeafList() instanceof YangLeaf) {
YangLeaf yangLeaf = ((YangLeaf) getReferredLeafOrLeafList());
YangType baseType = yangLeaf.getDataType();
if (baseType.getDataType() == YangDataTypes.LEAFREF) {
YangLeafRef referredLeafRefInfo = (YangLeafRef) (yangLeaf.getDataType().getDataTypeExtendedInfo());
/*
* Check whether the referred typedef is resolved.
*/
if (referredLeafRefInfo.getResolvableStatus() != INTRA_FILE_RESOLVED
&& referredLeafRefInfo.getResolvableStatus() != RESOLVED) {
throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
}
/*
* Check if the referred typedef is intra file resolved, if yes
* sets current status also to intra file resolved .
*/
if ((referredLeafRefInfo.getResolvableStatus() == INTRA_FILE_RESOLVED)) {
return INTRA_FILE_RESOLVED;
}
// Add the if-feature list from referred leafref to current leafref.
List<YangIfFeature> referredLeafIfFeatureListFromLeafref = referredLeafRefInfo.getIfFeatureList();
if (referredLeafIfFeatureListFromLeafref != null && !referredLeafIfFeatureListFromLeafref.isEmpty()) {
Iterator<YangIfFeature> referredLeafIfFeature = referredLeafIfFeatureListFromLeafref.iterator();
while (referredLeafIfFeature.hasNext()) {
YangIfFeature ifFeature = referredLeafIfFeature.next();
addIfFeatureList(ifFeature);
}
}
setEffectiveDataType(referredLeafRefInfo.getEffectiveDataType());
} else if (baseType.getDataType() == YangDataTypes.DERIVED) {
/*
* Check whether the referred typedef is resolved.
*/
if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED
&& baseType.getResolvableStatus() != RESOLVED) {
throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
}
/*
* Check if the referred typedef is intra file resolved, if yes
* sets current status also to intra file resolved .
*/
if ((baseType.getResolvableStatus() == INTRA_FILE_RESOLVED)) {
return INTRA_FILE_RESOLVED;
}
setEffectiveDataType(baseType);
} else {
setEffectiveDataType(baseType);
}
// Add the if-feature list from referred leaf to current leafref.
List<YangIfFeature> referredLeafIfFeatureList = yangLeaf.getIfFeatureList();
if (referredLeafIfFeatureList != null && !referredLeafIfFeatureList.isEmpty()) {
Iterator<YangIfFeature> referredLeafIfFeature = referredLeafIfFeatureList.iterator();
while (referredLeafIfFeature.hasNext()) {
YangIfFeature ifFeature = referredLeafIfFeature.next();
addIfFeatureList(ifFeature);
}
}
return RESOLVED;
} else if (getReferredLeafOrLeafList() instanceof YangLeafList) {
YangLeafList yangLeafList = ((YangLeafList) getReferredLeafOrLeafList());
YangType baseType = yangLeafList.getDataType();
if (baseType.getDataType() == YangDataTypes.LEAFREF) {
YangLeafRef referredLeafRefInfo = (YangLeafRef) yangLeafList.getDataType().getDataTypeExtendedInfo();
/*
* Check whether the referred typedef is resolved.
*/
if (referredLeafRefInfo.getResolvableStatus() != INTRA_FILE_RESOLVED
&& referredLeafRefInfo.getResolvableStatus() != RESOLVED) {
throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
}
/*
* Check if the referred typedef is intra file resolved, if yes
* sets current status also to intra file resolved .
*/
if ((referredLeafRefInfo.getResolvableStatus() == INTRA_FILE_RESOLVED)) {
return INTRA_FILE_RESOLVED;
}
// Add the if-feature list from referred leafref to current leafref.
List<YangIfFeature> referredLeafListIfFeatureListFromLeafref = referredLeafRefInfo.getIfFeatureList();
if (referredLeafListIfFeatureListFromLeafref != null
&& !referredLeafListIfFeatureListFromLeafref.isEmpty()) {
Iterator<YangIfFeature> referredLeafListIfFeature = referredLeafListIfFeatureListFromLeafref
.iterator();
while (referredLeafListIfFeature.hasNext()) {
YangIfFeature ifFeature = referredLeafListIfFeature.next();
addIfFeatureList(ifFeature);
}
}
setEffectiveDataType(referredLeafRefInfo.getEffectiveDataType());
} else if (baseType.getDataType() == YangDataTypes.DERIVED) {
/*
* Check whether the referred typedef is resolved.
*/
if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED
&& baseType.getResolvableStatus() != RESOLVED) {
throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
}
/*
* Check if the referred typedef is intra file resolved, if yes
* sets current status also to intra file resolved .
*/
if ((baseType.getResolvableStatus() == INTRA_FILE_RESOLVED)) {
return INTRA_FILE_RESOLVED;
}
setEffectiveDataType(baseType);
} else {
setEffectiveDataType(baseType);
}
// Add the if-feature list from referred leaf-list to current leafref.
List<YangIfFeature> referredLeafListIfFeatureList = yangLeafList.getIfFeatureList();
if (referredLeafListIfFeatureList != null && !referredLeafListIfFeatureList.isEmpty()) {
Iterator<YangIfFeature> referredLeafListIfFeature = referredLeafListIfFeatureList.iterator();
while (referredLeafListIfFeature.hasNext()) {
YangIfFeature ifFeature = referredLeafListIfFeature.next();
addIfFeatureList(ifFeature);
}
}
return RESOLVED;
} else {
throw new DataModelException("Linker Error: The leafref must refer only to leaf/leaf-list.");
}
}
}
......@@ -211,6 +211,11 @@ public class YangModule
private List<YangResolutionInfo> ifFeatureResolutionList;
/**
* leafref resolution list.
*/
private List<YangResolutionInfo> leafrefResolutionList;
/**
* Creates a YANG node of module type.
*/
public YangModule() {
......@@ -219,6 +224,7 @@ public class YangModule
derivedTypeResolutionList = new LinkedList<>();
usesResolutionList = new LinkedList<>();
ifFeatureResolutionList = new LinkedList<>();
leafrefResolutionList = new LinkedList<>();
importList = new LinkedList<YangImport>();
includeList = new LinkedList<YangInclude>();
listOfLeaf = new LinkedList<YangLeaf>();
......@@ -589,8 +595,10 @@ public class YangModule
return derivedTypeResolutionList;
} else if (type == ResolvableType.YANG_USES) {
return usesResolutionList;
} else {
} else if (type == ResolvableType.YANG_IF_FEATURE) {
return ifFeatureResolutionList;
} else {
return leafrefResolutionList;
}
}
......@@ -603,6 +611,8 @@ public class YangModule
usesResolutionList.add(resolutionInfo);
} else if (type == ResolvableType.YANG_IF_FEATURE) {
ifFeatureResolutionList.add(resolutionInfo);
} else {
leafrefResolutionList.add(resolutionInfo);
}
}
......@@ -615,6 +625,8 @@ public class YangModule
usesResolutionList = resolutionList;
} else if (type == ResolvableType.YANG_IF_FEATURE) {
ifFeatureResolutionList.add((YangResolutionInfo) resolutionList);
} else if (type == ResolvableType.YANG_LEAFREF) {
leafrefResolutionList = resolutionList;
}
}
......
......@@ -209,6 +209,11 @@ public class YangSubModule
private List<YangResolutionInfo> ifFeatureResolutionList;
/**
* leafref resolution list.
*/
private List<YangResolutionInfo> leafrefResolutionList;
/**
* Creates a sub module node.
*/
public YangSubModule() {
......@@ -216,6 +221,7 @@ public class YangSubModule
derivedTypeResolutionList = new LinkedList<>();
usesResolutionList = new LinkedList<>();
ifFeatureResolutionList = new LinkedList<>();
leafrefResolutionList = new LinkedList<>();
importList = new LinkedList<YangImport>();
includeList = new LinkedList<YangInclude>();
listOfLeaf = new LinkedList<YangLeaf>();
......@@ -551,8 +557,10 @@ public class YangSubModule
return derivedTypeResolutionList;
} else if (type == ResolvableType.YANG_USES) {
return usesResolutionList;
} else {
} else if (type == ResolvableType.YANG_IF_FEATURE) {
return ifFeatureResolutionList;
} else {
return leafrefResolutionList;
}
}
......@@ -565,6 +573,8 @@ public class YangSubModule
usesResolutionList.add(resolutionInfo);
} else if (type == ResolvableType.YANG_IF_FEATURE) {
ifFeatureResolutionList.add(resolutionInfo);
} else {
leafrefResolutionList.add(resolutionInfo);
}
}
......@@ -576,7 +586,9 @@ public class YangSubModule
} else if (type == ResolvableType.YANG_USES) {
usesResolutionList = resolutionList;
} else if (type == ResolvableType.YANG_IF_FEATURE) {
ifFeatureResolutionList = resolutionList;
ifFeatureResolutionList.add((YangResolutionInfo) resolutionList);
} else if (type == ResolvableType.YANG_LEAFREF) {
leafrefResolutionList = resolutionList;
}
}
......
......@@ -17,6 +17,7 @@
package org.onosproject.yangutils.datamodel;
import java.io.Serializable;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
......@@ -43,7 +44,7 @@ import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangData
* | bit | 9.7.4 | 0..n | - YangBit used in YangBits |
* | enum | 9.6.4 | 0..n | - YangEnum used in YangEnumeration |
* | length | 9.4.4 | 0..1 | - used for string |
* | path | 9.9.2 | 0..1 | - TODO leaf-ref |
* | path | 9.9.2 | 0..1 | - path for referred leaf/leaf-list |
* | pattern | 9.4.6 | 0..n | - used for string |
* | range | 9.2.4 | 0..1 | - used for integer data type |
* | require-instance | 9.13.2 | 0..1 | - TODO instance-identifier |
......@@ -67,11 +68,6 @@ public class YangType<T>
private YangNodeIdentifier nodeIdentifier;
/**
* Java package in which the Java type is defined.
*/
private String javaPackage;
/**
* YANG data type.
*/
private YangDataTypes dataType;
......@@ -137,24 +133,6 @@ public class YangType<T>
}
/**
* Returns the Java package where the type is defined.
*
* @return Java package where the type is defined
*/
public String getJavaPackage() {
return javaPackage;
}
/**
* Sets Java package where the type is defined.
*
* @param javaPackage Java package where the type is defined
*/
public void setJavaPackage(String javaPackage) {
this.javaPackage = javaPackage;
}
/**
* Returns the type of data.
*
* @return the data type
......@@ -209,6 +187,16 @@ public class YangType<T>
}
/**
* Resets the class attributes to its default value.
*/
public void resetYangType() {
nodeIdentifier = new YangNodeIdentifier();
resolvableStatus = ResolvableStatus.UNRESOLVED;
dataType = null;
dataTypeExtendedInfo = null;
}
/**
* Returns the type of the parsed data.
*
* @return returns TYPE_DATA
......
......@@ -24,6 +24,7 @@ import org.onosproject.yangutils.datamodel.ResolvableType;
import org.onosproject.yangutils.datamodel.YangIfFeature;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangReferenceResolver;
......@@ -171,6 +172,10 @@ public final class DataModelUtils {
.getEntityToResolve() instanceof YangIfFeature) {
resolutionNode.addToResolutionList(resolutionInfo,
ResolvableType.YANG_IF_FEATURE);
} else if (resolutionInfo.getEntityToResolveInfo()
.getEntityToResolve() instanceof YangLeafRef) {
resolutionNode.addToResolutionList(resolutionInfo,
ResolvableType.YANG_LEAFREF);
}
}
......
......@@ -25,14 +25,14 @@ public enum YangDataTypes {
*
* int8 represents integer values between -128 and 127, inclusively.
*/
INT8,
INT8("int8"),
/**
* Reference:RFC 6020.
*
* int16 represents integer values between -32768 and 32767, inclusively.
*/
INT16,
INT16("int16"),
/**
* Reference:RFC 6020.
......@@ -40,7 +40,7 @@ public enum YangDataTypes {
* int32 represents integer values between -2147483648 and 2147483647,
* inclusively.
*/
INT32,
INT32("int32"),
/**
* Reference:RFC 6020.
......@@ -48,28 +48,28 @@ public enum YangDataTypes {
* int64 represents integer values between -9223372036854775808 and
* 9223372036854775807, inclusively.
*/
INT64,
INT64("int64"),
/**
* Reference:RFC 6020.
*
* uint8 represents integer values between 0 and 255, inclusively.
*/
UINT8,
UINT8("uint8"),
/**
* Reference:RFC 6020.
*
* uint16 represents integer values between 0 and 65535, inclusively.
*/
UINT16,
UINT16("uint16"),
/**
* Reference:RFC 6020.
*
* uint32 represents integer values between 0 and 4294967295, inclusively.
*/
UINT32,
UINT32("uint32"),
/**
* Reference:RFC 6020.
......@@ -77,7 +77,7 @@ public enum YangDataTypes {
* uint64 represents integer values between 0 and 18446744073709551615,
* inclusively.
*/
UINT64,
UINT64("uint64"),
/**
* Reference:RFC 6020.
......@@ -88,7 +88,7 @@ public enum YangDataTypes {
* a negative power of ten, i.e., expressible as "i x 10^-n" where i is an
* integer64 and n is an integer between 1 and 18, inclusively.
*/
DECIMAL64, // TODO: need to implement in type.
DECIMAL64("decimal64"), // TODO: need to implement in type.
/**
* Reference:RFC 6020.
......@@ -97,14 +97,14 @@ public enum YangDataTypes {
* characters are tab, carriage return, line feed, and the legal characters
* of Unicode and ISO/IEC 10646
*/
STRING,
STRING("string"),
/**
* Reference:RFC 6020.
*
* The boolean built-in type represents a boolean value.
*/
BOOLEAN,
BOOLEAN("boolean"),
/**
* Reference:RFC 6020.
......@@ -112,7 +112,7 @@ public enum YangDataTypes {
* The enumeration built-in type represents values from a set of assigned
* names.
*/
ENUMERATION,
ENUMERATION("enumeration"),
/**
* Reference:RFC 6020.
......@@ -121,7 +121,7 @@ public enum YangDataTypes {
* set of flags identified by small integer position numbers starting at 0.
* Each bit number has an assigned name.
*/
BITS,
BITS("bits"),
/**
* Reference:RFC 6020.
......@@ -129,7 +129,7 @@ public enum YangDataTypes {
* The binary built-in type represents any binary data, i.e., a sequence of
* octets.
*/
BINARY,
BINARY("binary"),
/**
* Reference:RFC 6020.
......@@ -150,14 +150,14 @@ public enum YangDataTypes {
* more features, then the leaf with the leafref type MUST also be
* conditional based on at least the same set of features.
*/
LEAFREF, // TODO: need to implement in type.
LEAFREF("leafref"),
/**
* Reference:RFC 6020.
*
* The identityref type is used to reference an existing identity.
*/
IDENTITYREF,
IDENTITYREF("identityref"),
/**
* Reference:RFC 6020.
......@@ -167,7 +167,7 @@ public enum YangDataTypes {
*
* An empty type cannot have a default value.
*/
EMPTY,
EMPTY("empty"),
/**
* Reference:RFC 6020.
......@@ -189,7 +189,7 @@ public enum YangDataTypes {
* Any default value or "units" property defined in the member types is not
* inherited by the union type.
*/
UNION,
UNION("union"),
/**
* Reference:RFC 6020.
......@@ -212,12 +212,26 @@ public enum YangDataTypes {
* valid data. All such leaf nodes MUST reference existing nodes or leaf
* nodes with their default value in use for the data to be valid.
*/
INSTANCE_IDENTIFIER,
INSTANCE_IDENTIFIER("instance-identifier"),
/**
* Derived data type.
*/
DERIVED;
DERIVED("derived");
/**
* Defined type from the enum value.
*/
private String definedType;
/**
* Constructs type value from enum.
*
* @param definedType value of enum
*/
YangDataTypes(String definedType) {
this.definedType = definedType;
}
/**
* Returns YANG data type for corresponding type name.
......@@ -228,7 +242,7 @@ public enum YangDataTypes {
public static YangDataTypes getType(String name) {
name = name.replace("\"", "");
for (YangDataTypes yangDataType : values()) {
if (yangDataType.name().toLowerCase().equals(name)) {
if (yangDataType.definedType.toLowerCase().equals(name)) {
return yangDataType;
}
}
......
......@@ -161,6 +161,8 @@ public class YangLinkerManager
((YangReferenceResolver) yangNode).resolveInterFileLinking(ResolvableType.YANG_USES);
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_DERIVED_DATA_TYPE);
((YangReferenceResolver) yangNode)
.resolveInterFileLinking(ResolvableType.YANG_LEAFREF);
} catch (DataModelException e) {
String errorInfo = "Error in file: " + yangNode.getName() + " at line: "
+ e.getLineNumber() + " at position: " + e.getCharPositionInLine() + NEW_LINE + e.getMessage();
......
......@@ -22,7 +22,8 @@ import java.util.List;
import java.util.Stack;
import org.onosproject.yangutils.datamodel.Resolvable;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.ResolvableType;
import org.onosproject.yangutils.datamodel.YangAtomicPath;
import org.onosproject.yangutils.datamodel.YangDerivedInfo;
import org.onosproject.yangutils.datamodel.YangEntityToResolveInfo;
import org.onosproject.yangutils.datamodel.YangFeature;
......@@ -31,15 +32,29 @@ import org.onosproject.yangutils.datamodel.YangGrouping;
import org.onosproject.yangutils.datamodel.YangIfFeature;
import org.onosproject.yangutils.datamodel.YangImport;
import org.onosproject.yangutils.datamodel.YangInclude;
import org.onosproject.yangutils.datamodel.YangInput;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
import org.onosproject.yangutils.datamodel.YangOutput;
import org.onosproject.yangutils.datamodel.YangPathArgType;
import org.onosproject.yangutils.datamodel.YangPathPredicate;
import org.onosproject.yangutils.datamodel.YangReferenceResolver;
import org.onosproject.yangutils.datamodel.YangRelativePath;
import org.onosproject.yangutils.datamodel.YangResolutionInfo;
import org.onosproject.yangutils.datamodel.YangRpc;
import org.onosproject.yangutils.datamodel.YangSubModule;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.YangUses;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.linker.YangLinkingPhase;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTER_FILE_LINKED;
......@@ -52,6 +67,10 @@ import static org.onosproject.yangutils.linker.YangLinkingPhase.INTER_FILE;
import static org.onosproject.yangutils.linker.YangLinkingPhase.INTRA_FILE;
import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
import static org.onosproject.yangutils.utils.UtilConstants.INPUT;
import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
import static org.onosproject.yangutils.utils.UtilConstants.OUTPUT;
import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_LINKER_ERROR;
/**
......@@ -124,7 +143,7 @@ public class YangResolutionInfoImpl<T>
setCurReferenceResolver(dataModelRootNode);
// Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature.
// Current node to resolve, it can be a YANG type, YANG uses or YANG if-feature or YANG leafref.
T entityToResolve = getEntityToResolveInfo().getEntityToResolve();
// Check if linking is already done
......@@ -138,13 +157,15 @@ public class YangResolutionInfoImpl<T>
}
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than " +
"type/uses/if-feature");
"type/uses/if-feature/leafref");
}
// Push the initial entity to resolve in stack.
addInPartialResolvedStack(getEntityToResolveInfo());
linkAndResolvePartialResolvedStack();
addDerivedRefTypeToRefTypeResolutionList();
}
/**
......@@ -204,8 +225,10 @@ public class YangResolutionInfoImpl<T>
errorInfo = TYPEDEF_LINKER_ERROR;
} else if (resolvable instanceof YangUses) {
errorInfo = GROUPING_LINKER_ERROR;
} else {
} else if (resolvable instanceof YangIfFeature) {
errorInfo = FEATURE_LINKER_ERROR;
} else {
errorInfo = LEAFREF_LINKER_ERROR;
}
DataModelException dataModelException =
new DataModelException(errorInfo);
......@@ -222,11 +245,75 @@ public class YangResolutionInfoImpl<T>
}
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
throw new DataModelException(
"Data Model Exception: Entity to resolved is other than type/uses/if-feature/leafref");
}
}
}
/**
* Adds the leafref type to the type, which has derived type referring to typedef with leafref type.
*/
private void addDerivedRefTypeToRefTypeResolutionList() throws DataModelException {
YangNode potentialAncestorWithReferredNode = getEntityToResolveInfo().getHolderOfEntityToResolve();
// If holder is typedef return.
if (potentialAncestorWithReferredNode instanceof YangTypeDef) {
return;
}
// If entity is not type return.
if (!(getEntityToResolveInfo().getEntityToResolve() instanceof YangType)) {
return;
}
YangType yangType = (YangType) getEntityToResolveInfo().getEntityToResolve();
// If type is not resolved return.
if (yangType.getResolvableStatus() != RESOLVED) {
return;
}
YangDerivedInfo derivedInfo = (YangDerivedInfo) yangType.getDataTypeExtendedInfo();
/*
* If the derived types referred type is not leaf ref return
*/
if (derivedInfo.getEffectiveBuiltInType() != YangDataTypes.LEAFREF) {
return;
}
T extendedInfo = (T) derivedInfo.getReferredTypeDef().getTypeDefBaseType().getDataTypeExtendedInfo();
while (extendedInfo instanceof YangDerivedInfo) {
YangDerivedInfo derivedInfoFromTypedef = (YangDerivedInfo) extendedInfo;
extendedInfo = (T) derivedInfoFromTypedef.getReferredTypeDef().getTypeDefBaseType()
.getDataTypeExtendedInfo();
}
/*
* Backup the derived types leaf ref info, delete all the info in
* current type, but for resolution status as resolved. Copy the backed
* up leaf ref to types extended info, create a leaf ref resolution info
* using the current resolution info and add to leaf ref resolution
* list.
*/
YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
yangType.resetYangType();
yangType.setResolvableStatus(RESOLVED);
yangType.setDataType(YangDataTypes.LEAFREF);
yangType.setDataTypeName(LEAFREF);
yangType.setDataTypeExtendedInfo(leafRefInTypeDef);
leafRefInTypeDef.setResolvableStatus(UNRESOLVED);
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<>(leafRefInTypeDef,
potentialAncestorWithReferredNode, getLineNumber(), getCharPosition());
getCurReferenceResolver().addToResolutionList(resolutionInfoImpl,
ResolvableType.YANG_LEAFREF);
getCurReferenceResolver().resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
}
/**
......@@ -237,7 +324,7 @@ public class YangResolutionInfoImpl<T>
((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != INTRA_FILE_RESOLVED
&& ((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() != UNDEFINED) {
// Sets the resolution status in inside the type/uses/if-feature.
// Sets the resolution status in inside the type/uses/if-feature/leafref.
((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(RESOLVED);
}
}
......@@ -270,6 +357,9 @@ public class YangResolutionInfoImpl<T>
if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
resolveSelfFileLinkingForIfFeature(potentialAncestorWithReferredNode);
return;
} else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
resolveSelfFileLinkingForLeafref(potentialAncestorWithReferredNode);
return;
} else {
/**
......@@ -300,6 +390,91 @@ public class YangResolutionInfoImpl<T>
}
/**
* Resolves self file linking for leafref.
*
* @param potentialAncestorWithReferredNode leafref holder node
* @throws DataModelException a violation of data model rules
*/
private void resolveSelfFileLinkingForLeafref(YangNode potentialAncestorWithReferredNode)
throws DataModelException {
YangNode ancestorWithTheReferredNode = potentialAncestorWithReferredNode;
YangLeafRef leafref = (YangLeafRef) getCurrentEntityToResolveFromStack();
boolean referredLeafFound = false;
/*
* Takes absolute path and takes the root node as module/sub-module,
* then sends the list of nodes for finding the target leaf.
*/
if (leafref.getPathType() == YangPathArgType.ABSOLUTE_PATH) {
List<YangAtomicPath> atomicPathList = leafref.getAtomicPath();
if (atomicPathList != null && !atomicPathList.isEmpty()) {
Iterator<YangAtomicPath> listOfYangAtomicPath = atomicPathList.listIterator();
if (getCurReferenceResolver() instanceof YangModule) {
YangModule rootNode = (YangModule) getCurReferenceResolver();
// Sends list of nodes for finding the target leaf.
referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
referredLeafFound, potentialAncestorWithReferredNode);
} else if (getCurReferenceResolver() instanceof YangSubModule) {
YangSubModule rootNode = (YangSubModule) getCurReferenceResolver();
// Sends list of nodes for finding the target leaf.
referredLeafFound = isLeafReferenceFound(listOfYangAtomicPath, rootNode,
referredLeafFound, potentialAncestorWithReferredNode);
}
}
/*
* Takes relative path, goes to the parent node by using the
* ancestor count and sends the list of nodes for finding the target
* leaf.
*/
} else if (leafref.getPathType() == YangPathArgType.RELATIVE_PATH) {
YangRelativePath yangRelativePath = leafref.getRelativePath();
int parentNodes = yangRelativePath.getAncestorNodeCount();
List<YangAtomicPath> atomicPathList = yangRelativePath.getAtomicPathList();
if (atomicPathList != null && !atomicPathList.isEmpty()) {
Iterator<YangAtomicPath> listOfAtomicPath = atomicPathList.listIterator();
// Gets the root node from ancestor count.
YangNode rootparentNode = getRootNodeWithAncestorCount(parentNodes, ancestorWithTheReferredNode);
// Sends list of nodes for finding the target leaf.
referredLeafFound = isLeafReferenceFound(listOfAtomicPath, rootparentNode,
referredLeafFound, potentialAncestorWithReferredNode);
}
}
if (referredLeafFound) {
return;
}
/*
* In case prefix is not present it's a candidate for inter-file
* resolution via include list.
*/
if (getRefPrefix() == null) {
((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTRA_FILE_RESOLVED);
}
}
/**
* Returns the root parent with respect to the ancestor count from leafref.
*
* @param ancestorCount count of node where parent node can be reached
* @param currentParent current parent node
* @return root node
* @throws DataModelException a violation of data model rules
*/
private YangNode getRootNodeWithAncestorCount(int ancestorCount, YangNode currentParent)
throws DataModelException {
int currentParentCount = 1;
while (currentParentCount < ancestorCount) {
if (currentParent.getParent() == null) {
throw new DataModelException("YANG file error: The target node of leafref is invalid.");
}
currentParent = currentParent.getParent();
currentParentCount = currentParentCount + 1;
}
return currentParent;
}
/**
* Resolves self file linking for if-feature.
*
* @param potentialAncestorWithReferredNode if-feature holder node
......@@ -333,6 +508,289 @@ public class YangResolutionInfoImpl<T>
}
}
/**
* Returns the status of the referred leaf/leaf-list found for leafref.
*
* @param listOfYangAtomicPath list of atomic paths
* @param ancestorWithTheReferredNode the parent node of leafref
* @param referredLeafFound status of referred leaf/leaf-list
* @param potentialAncestorWithReferredNode holder of the leafref leaf
* @return status of referred leaf
* @throws DataModelException a violation of data model rules
*/
private boolean isLeafReferenceFound(Iterator<YangAtomicPath> listOfYangAtomicPath,
YangNode ancestorWithTheReferredNode, boolean referredLeafFound, YangNode potentialAncestorWithReferredNode)
throws DataModelException {
while (listOfYangAtomicPath.hasNext()) {
YangAtomicPath atomicPath = listOfYangAtomicPath.next();
String nodeName = atomicPath.getNodeIdentifier().getName();
// When child is not present, only leaf/leaf-list is available in the node.
if (ancestorWithTheReferredNode.getChild() == null) {
referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode, nodeName, (T) LINKED);
break;
}
ancestorWithTheReferredNode = ancestorWithTheReferredNode.getChild();
// Checks all the siblings under the node and returns the matched node.
YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(ancestorWithTheReferredNode, nodeName);
// When node is not found in all the siblings, leaf-list may be the node we have to find.
if (nodeFound == null) {
referredLeafFound = isReferredLeafOrLeafListFound(ancestorWithTheReferredNode.getParent(), nodeName,
(T) LINKED);
} else {
ancestorWithTheReferredNode = nodeFound;
// For the node check if path predicate is present and fill its values.
List<YangPathPredicate> pathPredicateList = atomicPath.getPathPredicatesList();
if (pathPredicateList != null && !pathPredicateList.isEmpty()) {
Iterator<YangPathPredicate> listOfYangPathPredicate = pathPredicateList.listIterator();
fillPathPredicatesForTheNode(ancestorWithTheReferredNode, listOfYangPathPredicate,
potentialAncestorWithReferredNode);
}
}
// If leaf is also not found and node is also not found return the status as false.
if (!referredLeafFound && nodeFound == null) {
break;
}
}
return referredLeafFound;
}
/**
* Fills the referred leaf or leaf-list inside the path predicates.
*
* @param ancestorWithTheReferredNode the actual node where YANG list will be present
* @param listOfYangPathPredicate the path predicates present for the node
* @param potentialAncestorWithReferredNode the current leaf node parent
* @throws DataModelException a violation of data model rules
*/
private void fillPathPredicatesForTheNode(YangNode ancestorWithTheReferredNode,
Iterator<YangPathPredicate> listOfYangPathPredicate, YangNode potentialAncestorWithReferredNode)
throws DataModelException {
while (listOfYangPathPredicate.hasNext()) {
if (!(ancestorWithTheReferredNode instanceof YangList)) {
throw new DataModelException("YANG file error: The path predicates are applicable only for list");
}
YangPathPredicate pathPredicate = listOfYangPathPredicate.next();
YangNodeIdentifier leftNode = pathPredicate.getNodeIdentifier();
YangRelativePath relativePath = pathPredicate.getRightRelativePath();
// Checks that the left axis is filled in the path predicate.
boolean isLeftLeafOrLeafListSetForLeftAxis = getLeftLeafOrLeafListInPredicate(
(YangList) ancestorWithTheReferredNode, pathPredicate, leftNode);
if (!isLeftLeafOrLeafListSetForLeftAxis) {
throw new DataModelException(
"YANG file error: The path predicate is not referring to an existing leaf/leaflist");
}
int parentNodes = relativePath.getAncestorNodeCount();
// Finds the root node for the right relative path.
YangNode rootParentNode = getRootNodeWithAncestorCount(parentNodes, potentialAncestorWithReferredNode);
// Finds the leaf/leaf-list from the right side relative path.
resolveRightAxisNodeInPathPredicate(relativePath, rootParentNode, pathPredicate);
}
}
/**
* Resolves the right axis node in the path predicate.
*
* @param relativePath the relative path in the path predicate
* @param rootParentNode parent node from where the node has to be found
* @param pathPredicate data tree reference in YANG list
* @throws DataModelException a violation of data model rules
*/
private void resolveRightAxisNodeInPathPredicate(YangRelativePath relativePath, YangNode rootParentNode,
YangPathPredicate pathPredicate) throws DataModelException {
List<YangAtomicPath> absolutePathList = relativePath.getAtomicPathList();
if (absolutePathList != null && !absolutePathList.isEmpty()) {
Iterator<YangAtomicPath> listOfYangAtomicPathForRightRelative = absolutePathList.listIterator();
while (listOfYangAtomicPathForRightRelative.hasNext()) {
boolean isRightAxisNodeFound = false;
YangAtomicPath absolutePathInPredicate = listOfYangAtomicPathForRightRelative.next();
String nodeNameInAtomicPath = absolutePathInPredicate.getNodeIdentifier().getName();
// When child is not there check the leaf/leaf-list.
if (rootParentNode.getChild() == null) {
isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode,
nodeNameInAtomicPath, (T) pathPredicate);
if (!isRightAxisNodeFound) {
throw new DataModelException(
"YANG file error: The path predicates is not referring to an existing leaf/leaflist");
}
break;
}
rootParentNode = rootParentNode.getChild();
YangNode nodeFoundInTheRelativePath = isReferredNodeInSiblingProcessedForLeafref(
rootParentNode, nodeNameInAtomicPath);
if (nodeFoundInTheRelativePath == null) {
// When node is not found check the leaf/leaf-list.
isRightAxisNodeFound = isReferredLeafOrLeafListFound(rootParentNode.getParent(),
nodeNameInAtomicPath, (T) pathPredicate);
} else {
rootParentNode = nodeFoundInTheRelativePath;
}
if (!isRightAxisNodeFound && nodeFoundInTheRelativePath == null) {
throw new DataModelException(
"YANG file error: The path predicates is not referring to an existing leaf/leaflist");
}
}
}
}
/**
* Returns the status, if referred leaf/leaf-list is found.
*
* @param ancestorWithTheReferredNode the parent node of leaf/leaf-list
* @param nodeName the name of the leaf/leaf-list
* @param statusOrPathPredicate the status to be set for the leaf-ref or the path predicate
* @return status of the target node is found
* @throws DataModelException a violation of data model rules
*/
private boolean isReferredLeafOrLeafListFound(YangNode ancestorWithTheReferredNode, String nodeName,
T statusOrPathPredicate) throws DataModelException {
if (!(ancestorWithTheReferredNode instanceof YangLeavesHolder)) {
throw new DataModelException("Yang file error: The target node of leafref is invalid.");
}
YangLeavesHolder leavesHolder = (YangLeavesHolder) ancestorWithTheReferredNode;
if (leavesHolder.getListOfLeaf() != null) {
Iterator<YangLeaf> yangLeavesList = leavesHolder.getListOfLeaf().listIterator();
while (yangLeavesList.hasNext()) {
YangLeaf yangleaf = yangLeavesList.next();
if (yangleaf.getName().contentEquals(nodeName)) {
if (statusOrPathPredicate instanceof ResolvableStatus) {
ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
// Sets the referred leaf to YANG leafref.
((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangleaf);
// Adds reference link of entity to the node under resolution.
addReferredEntityLink(ancestorWithTheReferredNode, status);
addUnResolvedLeafRefTypeToStack((T) yangleaf, ancestorWithTheReferredNode);
return true;
} else if (statusOrPathPredicate instanceof YangPathPredicate) {
YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
// Sets the right axis node.
pathPredicate.setRightAxisNode(yangleaf);
return true;
} else {
throw new DataModelException("YANG file error: The target node of leafref is invalid.");
}
}
}
}
if (leavesHolder.getListOfLeafList() != null) {
Iterator<YangLeafList> yangLeafListList = leavesHolder.getListOfLeafList().listIterator();
while (yangLeafListList.hasNext()) {
YangLeafList yangLeaflist = yangLeafListList.next();
if (yangLeaflist.getName().contentEquals(nodeName)) {
if (statusOrPathPredicate instanceof ResolvableStatus) {
ResolvableStatus status = (ResolvableStatus) statusOrPathPredicate;
// Sets the referred leaf-list to YANG leafref.
((YangLeafRef) getCurrentEntityToResolveFromStack()).setReferredLeafOrLeafList(yangLeaflist);
// Adds reference link of entity to the node under resolution.
addReferredEntityLink(ancestorWithTheReferredNode, status);
addUnResolvedLeafRefTypeToStack((T) yangLeaflist, ancestorWithTheReferredNode);
return true;
} else if (statusOrPathPredicate instanceof YangPathPredicate) {
YangPathPredicate pathPredicate = (YangPathPredicate) statusOrPathPredicate;
pathPredicate.setRightAxisNode(yangLeaflist);
return true;
} else {
throw new DataModelException("YANG file error: The target node of leafref is invalid.");
}
}
}
}
return false;
}
/**
* Adds the unresolved constructs to stack which has to be resolved for leafref.
*
* @param yangleafOrLeafList YANG leaf or leaf list which holds the type
* @param ancestorWithTheReferredNode holder of the YANG leaf or leaf list
*/
private void addUnResolvedLeafRefTypeToStack(T yangleafOrLeafList, YangNode ancestorWithTheReferredNode) {
YangType referredTypeInLeafOrLeafList;
if (yangleafOrLeafList instanceof YangLeaf) {
YangLeaf leaf = (YangLeaf) yangleafOrLeafList;
referredTypeInLeafOrLeafList = leaf.getDataType();
if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
unResolvedEntityInfo.setEntityToResolve((YangLeafRef<?>) leaf.getDataType().getDataTypeExtendedInfo());
unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
} else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
}
} else {
YangLeafList leafList = (YangLeafList) yangleafOrLeafList;
referredTypeInLeafOrLeafList = leafList.getDataType();
if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.LEAFREF) {
YangEntityToResolveInfoImpl<YangLeafRef<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
unResolvedEntityInfo
.setEntityToResolve((YangLeafRef<?>) leafList.getDataType().getDataTypeExtendedInfo());
unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
} else if (referredTypeInLeafOrLeafList.getDataType() == YangDataTypes.DERIVED) {
YangEntityToResolveInfoImpl<YangType<?>> unResolvedEntityInfo = new YangEntityToResolveInfoImpl<>();
unResolvedEntityInfo.setEntityToResolve(referredTypeInLeafOrLeafList);
unResolvedEntityInfo.setHolderOfEntityToResolve(ancestorWithTheReferredNode);
addInPartialResolvedStack((YangEntityToResolveInfoImpl<T>) unResolvedEntityInfo);
}
}
}
/**
* Returns true if referred leaf/leaf-list is found in a particular node. This is for path in path predicate.
*
* @param listForLeaf list node where referred leaf is found
* @param pathPredicate path predicate instance where the value of nodes to be found are available
* @param leftNode node identifier of the left side parameter in path predicate
* @return status of the leaf/leaf-list found
*/
private boolean getLeftLeafOrLeafListInPredicate(YangList listForLeaf, YangPathPredicate pathPredicate,
YangNodeIdentifier leftNode) {
if (listForLeaf.getListOfLeaf() != null) {
Iterator<YangLeaf> yangLeavesUnderList = listForLeaf.getListOfLeaf().listIterator();
while (yangLeavesUnderList.hasNext()) {
YangLeaf yangleafUnderList = yangLeavesUnderList.next();
if (yangleafUnderList.getName().contentEquals(leftNode.getName())) {
pathPredicate.setLeftAxisNode(yangleafUnderList);
return true;
}
}
}
if (listForLeaf.getListOfLeafList() != null) {
Iterator<YangLeafList> yangLeavesListUnderList = listForLeaf.getListOfLeafList().listIterator();
while (yangLeavesListUnderList.hasNext()) {
YangLeafList yangleafListUnderList = yangLeavesListUnderList.next();
if (yangleafListUnderList.getName().contentEquals(leftNode.getName())) {
pathPredicate.setLeftAxisNode(yangleafListUnderList);
return true;
}
}
}
return false;
}
/**
* Returns feature holder(module/sub-module node) .
......@@ -362,12 +820,70 @@ public class YangResolutionInfoImpl<T>
}
/**
* Checks for the referred parent node for the leafref path.
*
* @param potentialReferredNode potential referred node
* @return the reffered parent node of leaf/leaf-list
* @throws DataModelException data model errors
*/
private YangNode isReferredNodeInSiblingProcessedForLeafref(YangNode potentialReferredNode, String referredNodeName)
throws DataModelException {
while (potentialReferredNode != null) {
if (potentialReferredNode instanceof YangInput) {
if (referredNodeName.equalsIgnoreCase(INPUT)) {
return potentialReferredNode;
}
} else if (potentialReferredNode instanceof YangOutput) {
if (referredNodeName.equalsIgnoreCase(OUTPUT)) {
return potentialReferredNode;
}
}
// Check if the potential referred node is the actual referred node
if (isReferredNodeForLeafref(potentialReferredNode, referredNodeName)) {
if (potentialReferredNode instanceof YangGrouping || potentialReferredNode instanceof YangTypeDef) {
if (potentialReferredNode.getParent() instanceof YangRpc) {
potentialReferredNode = potentialReferredNode.getNextSibling();
} else {
throw new DataModelException("YANG file error: The target node of leafref is invalid.");
}
}
return potentialReferredNode;
}
potentialReferredNode = potentialReferredNode.getNextSibling();
}
return null;
}
/**
* Checks if the current reference node name and the name in the path are equal.
*
* @param currentReferredNode the node where the reference is pointed
* @param nameOfNodeinPath name of the node in the path
* @return status of the match between the name
* @throws DataModelException a violation of data model rules
*/
private boolean isReferredNodeForLeafref(YangNode currentReferredNode, String nameOfNodeinPath)
throws DataModelException {
if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
/*
* Check if name of node name matches with the current reference
* node.
*/
return currentReferredNode.getName().contentEquals(nameOfNodeinPath);
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than leafref");
}
}
/**
* Checks for the referred node defined in a ancestor scope.
*
* @param potentialReferredNode potential referred node
* @return status of resolution and updating the partial resolved stack with
* the any recursive references
* @throws DataModelException data model errors
* @throws DataModelException a violation of data model rules
*/
private boolean isReferredNodeInSiblingListProcessed(YangNode potentialReferredNode)
throws DataModelException {
......@@ -502,6 +1018,8 @@ public class YangResolutionInfoImpl<T>
.setRefGroup((YangGrouping) referredNode);
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
// do nothing , referred node is already set
} else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
// do nothing , referred node is already set
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
}
......@@ -541,7 +1059,8 @@ public class YangResolutionInfoImpl<T>
addUnResolvedUsesToStack(referredNode);
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
addUnResolvedIfFeatureToStack(referredNode);
} else {
} else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
// do nothing , referred node is already set
throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
}
}
......@@ -706,6 +1225,9 @@ public class YangResolutionInfoImpl<T>
// Inter file linking and resolution.
linkInterFileAndResolve();
// Resolve the derived types having leafref.
addDerivedRefTypeToRefTypeResolutionList();
}
/**
......@@ -723,6 +1245,8 @@ public class YangResolutionInfoImpl<T>
refPrefix = ((YangUses) getCurrentEntityToResolveFromStack()).getPrefix();
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
refPrefix = ((YangIfFeature) getCurrentEntityToResolveFromStack()).getPrefix();
} else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
refPrefix = refPrefixForLeafRef();
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
}
......@@ -730,6 +1254,27 @@ public class YangResolutionInfoImpl<T>
}
/**
* Returns the referenced prefix for leafref under resolution.
*
* @return referenced prefix of leafref under resolution
*/
private String refPrefixForLeafRef() {
String refPrefix;
if (((YangLeafRef) getCurrentEntityToResolveFromStack()).getPathType() == YangPathArgType.ABSOLUTE_PATH) {
List<YangAtomicPath> theList = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getAtomicPath();
YangAtomicPath absPath = theList.iterator().next();
refPrefix = absPath.getNodeIdentifier().getPrefix();
} else {
YangRelativePath relativePath = ((YangLeafRef) getCurrentEntityToResolveFromStack()).getRelativePath();
List<YangAtomicPath> theList = relativePath.getAtomicPathList();
YangAtomicPath absPath = theList.iterator().next();
refPrefix = absPath.getNodeIdentifier().getPrefix();
}
return refPrefix;
}
/**
* Performs inter file linking and resolution.
*
* @throws DataModelException a violation in data model rule
......@@ -838,9 +1383,19 @@ public class YangResolutionInfoImpl<T>
((YangIfFeature) getCurrentEntityToResolveFromStack()).setResolvableStatus(UNDEFINED);
return;
}
// Exception when referred typedef/grouping is not found.
DataModelException dataModelException = new DataModelException("YANG file error: Referred " +
"typedef/grouping for a given type/uses can't be found.");
// If current entity is still not resolved, then
// linking/resolution has failed.
String errorInfo;
if (getCurrentEntityToResolveFromStack() instanceof YangType) {
errorInfo = TYPEDEF_LINKER_ERROR;
} else if (getCurrentEntityToResolveFromStack() instanceof YangUses) {
errorInfo = GROUPING_LINKER_ERROR;
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
errorInfo = FEATURE_LINKER_ERROR;
} else {
errorInfo = LEAFREF_LINKER_ERROR;
}
DataModelException dataModelException = new DataModelException(errorInfo);
dataModelException.setLine(getLineNumber());
dataModelException.setCharPosition(getCharPosition());
throw dataModelException;
......@@ -849,8 +1404,19 @@ public class YangResolutionInfoImpl<T>
* If referred node is already linked, then just change the status
* and push to the stack.
*/
((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
if (referredNode instanceof YangLeaf) {
YangLeaf yangleaf = (YangLeaf) referredNode;
addUnResolvedLeafRefTypeToStack((T) yangleaf, (YangNode) yangleaf.getContainedIn());
} else if (referredNode instanceof YangLeafList) {
YangLeafList yangLeafList = (YangLeafList) referredNode;
addUnResolvedLeafRefTypeToStack((T) yangLeafList, (YangNode) yangLeafList.getContainedIn());
}
} else {
((Resolvable) getCurrentEntityToResolveFromStack()).setResolvableStatus(INTER_FILE_LINKED);
addUnresolvedRecursiveReferenceToStack((YangNode) referredNode);
}
}
}
......@@ -874,6 +1440,15 @@ public class YangResolutionInfoImpl<T>
linkedNode = findRefGrouping(yangInclude.getIncludedNode());
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
linkedNode = findRefFeature(yangInclude.getIncludedNode());
} else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
boolean referredNode = findRefLeaf(yangInclude.getIncludedNode());
/*
* Update the current reference resolver to external
* module/sub-module containing the referred typedef/grouping.
*/
setCurReferenceResolver((YangReferenceResolver) yangInclude.getIncludedNode());
return referredNode;
}
if (linkedNode != null) {
// Add the link to external entity.
......@@ -917,6 +1492,16 @@ public class YangResolutionInfoImpl<T>
linkedNode = findRefGrouping(yangImport.getImportedNode());
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
linkedNode = findRefFeature(yangImport.getImportedNode());
} else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
boolean referredNode = findRefLeaf(yangImport.getImportedNode());
/*
* Update the current reference resolver to external
* module/sub-module containing the referred
* typedef/grouping.
*/
setCurReferenceResolver((YangReferenceResolver) yangImport.getImportedNode());
return referredNode;
}
if (linkedNode != null) {
// Add the link to external entity.
......@@ -944,6 +1529,44 @@ public class YangResolutionInfoImpl<T>
}
/**
* Returns the status of referred leaf.
*
* @param importedNode the root node from a YANG file
* @return status of the referred leaf
* @throws DataModelException
*/
private boolean findRefLeaf(YangNode importedNode) throws DataModelException {
boolean isReferredNodeFound = false;
List<YangAtomicPath> absolutePathList = ((YangLeafRef) getCurrentEntityToResolveFromStack())
.getAtomicPath();
if (absolutePathList != null && !absolutePathList.isEmpty()) {
Iterator<YangAtomicPath> listOfYangAtomicPath = absolutePathList.listIterator();
while (listOfYangAtomicPath.hasNext()) {
YangAtomicPath absolutePath = listOfYangAtomicPath.next();
String nodeName = absolutePath.getNodeIdentifier().getName();
if (importedNode.getChild() == null) {
isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode, nodeName, (T) INTER_FILE_LINKED);
break;
}
importedNode = importedNode.getChild();
YangNode nodeFound = isReferredNodeInSiblingProcessedForLeafref(importedNode, nodeName);
if (nodeFound == null) {
isReferredNodeFound = isReferredLeafOrLeafListFound(importedNode.getParent(), nodeName,
(T) INTER_FILE_LINKED);
} else {
importedNode = nodeFound;
}
}
}
// TODO: Path predicates filling for inter file has to be done.
return isReferredNodeFound;
}
/**
* Returns referred typedef/grouping node.
*
* @return referred typedef/grouping node
......@@ -959,6 +1582,8 @@ public class YangResolutionInfoImpl<T>
return (T) ((YangUses) getCurrentEntityToResolveFromStack()).getRefGroup();
} else if (getCurrentEntityToResolveFromStack() instanceof YangIfFeature) {
return (T) ((YangIfFeature) getCurrentEntityToResolveFromStack()).getReferredFeatureHolder();
} else if (getCurrentEntityToResolveFromStack() instanceof YangLeafRef) {
return (T) ((YangLeafRef) getCurrentEntityToResolveFromStack()).getReferredLeafOrLeafList();
} else {
throw new DataModelException("Data Model Exception: Entity to resolved is other than type/uses");
}
......
......@@ -16,7 +16,6 @@
// Generated from GeneratedYang.g4 by ANTLR 4.5
package org.onosproject.yangutils.parser.antlrgencode;
import org.antlr.v4.runtime.tree.ParseTreeListener;
......@@ -1950,4 +1949,18 @@ public interface GeneratedYangListener extends ParseTreeListener {
*/
void exitAnnotationIdentifier(GeneratedYangParser.AnnotationIdentifierContext
currentContext);
/**
* Enters a parse tree produced by GeneratedYangParser for grammar rule require instance.
*
* @param currentContext current context in the parsed tree
*/
void enterRequireInstance(GeneratedYangParser.RequireInstanceContext currentContext);
/**
* Exits a parse tree produced by GeneratedYangParser for grammar require instance.
*
* @param currentContext current context in the parsed tree
*/
void exitRequireInstance(GeneratedYangParser.RequireInstanceContext currentContext);
}
......
......@@ -49,6 +49,7 @@ import org.onosproject.yangutils.parser.impl.listeners.InputListener;
import org.onosproject.yangutils.parser.impl.listeners.KeyListener;
import org.onosproject.yangutils.parser.impl.listeners.LeafListListener;
import org.onosproject.yangutils.parser.impl.listeners.LeafListener;
import org.onosproject.yangutils.parser.impl.listeners.LeafrefListener;
import org.onosproject.yangutils.parser.impl.listeners.LengthRestrictionListener;
import org.onosproject.yangutils.parser.impl.listeners.ListListener;
import org.onosproject.yangutils.parser.impl.listeners.MandatoryListener;
......@@ -56,16 +57,18 @@ import org.onosproject.yangutils.parser.impl.listeners.MaxElementsListener;
import org.onosproject.yangutils.parser.impl.listeners.MinElementsListener;
import org.onosproject.yangutils.parser.impl.listeners.ModuleListener;
import org.onosproject.yangutils.parser.impl.listeners.MustListener;
import org.onosproject.yangutils.parser.impl.listeners.NotificationListener;
import org.onosproject.yangutils.parser.impl.listeners.NamespaceListener;
import org.onosproject.yangutils.parser.impl.listeners.NotificationListener;
import org.onosproject.yangutils.parser.impl.listeners.OrganizationListener;
import org.onosproject.yangutils.parser.impl.listeners.OutputListener;
import org.onosproject.yangutils.parser.impl.listeners.PathListener;
import org.onosproject.yangutils.parser.impl.listeners.PatternRestrictionListener;
import org.onosproject.yangutils.parser.impl.listeners.PositionListener;
import org.onosproject.yangutils.parser.impl.listeners.PrefixListener;
import org.onosproject.yangutils.parser.impl.listeners.PresenceListener;
import org.onosproject.yangutils.parser.impl.listeners.RangeRestrictionListener;
import org.onosproject.yangutils.parser.impl.listeners.ReferenceListener;
import org.onosproject.yangutils.parser.impl.listeners.RequireInstanceListener;
import org.onosproject.yangutils.parser.impl.listeners.RevisionDateListener;
import org.onosproject.yangutils.parser.impl.listeners.RevisionListener;
import org.onosproject.yangutils.parser.impl.listeners.RpcListener;
......@@ -81,9 +84,9 @@ import org.onosproject.yangutils.parser.impl.listeners.ValueListener;
import org.onosproject.yangutils.parser.impl.listeners.VersionListener;
import org.onosproject.yangutils.parser.impl.listeners.WhenListener;
import static org.onosproject.yangutils.utils.UtilConstants.UNSUPPORTED_YANG_CONSTRUCT;
import static org.onosproject.yangutils.utils.UtilConstants.CURRENTLY_UNSUPPORTED;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.handleUnsupportedYangConstruct;
import static org.onosproject.yangutils.utils.UtilConstants.CURRENTLY_UNSUPPORTED;
import static org.onosproject.yangutils.utils.UtilConstants.UNSUPPORTED_YANG_CONSTRUCT;
/**
* Represents ANTLR generates parse-tree. ANTLR generates a parse-tree listener interface that responds to events
......@@ -667,17 +670,17 @@ public class TreeWalkListener implements GeneratedYangListener {
@Override
public void enterLeafrefSpecification(GeneratedYangParser.LeafrefSpecificationContext ctx) {
// do nothing.
LeafrefListener.processLeafrefEntry(this, ctx);
}
@Override
public void exitLeafrefSpecification(GeneratedYangParser.LeafrefSpecificationContext ctx) {
// do nothing.
LeafrefListener.processLeafrefExit(this, ctx);
}
@Override
public void enterPathStatement(GeneratedYangParser.PathStatementContext ctx) {
handleUnsupportedYangConstruct(YangConstructType.PATH_DATA, ctx, CURRENTLY_UNSUPPORTED);
PathListener.processPathEntry(this, ctx);
}
@Override
......@@ -687,7 +690,7 @@ public class TreeWalkListener implements GeneratedYangListener {
@Override
public void enterRequireInstanceStatement(GeneratedYangParser.RequireInstanceStatementContext ctx) {
handleUnsupportedYangConstruct(YangConstructType.REQUIRE_INSTANCE_DATA, ctx, UNSUPPORTED_YANG_CONSTRUCT);
RequireInstanceListener.processRequireInstanceEntry(this, ctx);
}
@Override
......@@ -1489,6 +1492,16 @@ public class TreeWalkListener implements GeneratedYangListener {
}
@Override
public void enterRequireInstance(GeneratedYangParser.RequireInstanceContext ctx) {
// do nothing.
}
@Override
public void exitRequireInstance(GeneratedYangParser.RequireInstanceContext ctx) {
// do nothing.
}
@Override
public void enterFraction(GeneratedYangParser.FractionContext ctx) {
// TODO: implement the method.
}
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.linker.impl.YangResolutionInfoImpl;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
import static org.onosproject.yangutils.datamodel.utils.YangConstructType.LEAFREF_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
/*
* Reference: RFC6020 and YANG ANTLR Grammar
*
* ABNF grammar as per RFC6020
* type-body-stmts = numerical-restrictions /
* decimal64-specification /
* string-restrictions /
* enum-specification /
* leafref-specification /
* identityref-specification /
* instance-identifier-specification /
* bits-specification /
* union-specification
*
* leafref-specification =
* ;; these stmts can appear in any order
* path-stmt stmtsep
* [require-instance-stmt stmtsep]
*
* ANTLR grammar rule
*
* typeBodyStatements : numericalRestrictions | stringRestrictions | enumSpecification
* | leafrefSpecification | identityrefSpecification | instanceIdentifierSpecification
* | bitsSpecification | unionSpecification;
*
* leafrefSpecification : (pathStatement (requireInstanceStatement)?) | ((requireInstanceStatement)? pathStatement);
*/
/**
* Represents listener based call back function corresponding to the
* "leafref" rule defined in ANTLR grammar file for corresponding ABNF rule
* in RFC 6020.
*/
public final class LeafrefListener {
/**
* Creates a new leafref listener.
*/
private LeafrefListener() {
}
/**
* It is called when parser receives an input matching the grammar rule
* (leafref), perform validations and updates the data model tree.
*
* @param listener listener's object
* @param ctx context object of the grammar rule
*/
public static void processLeafrefEntry(TreeWalkListener listener,
GeneratedYangParser.LeafrefSpecificationContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, LEAFREF_DATA, "", ENTRY);
int errorLine = ctx.getStart().getLine();
int errorPosition = ctx.getStart().getCharPositionInLine();
YangLeafRef<?> leafRef = new YangLeafRef<>();
Parsable typeData = listener.getParsedDataStack().pop();
if (!(typeData instanceof YangType)) {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LEAFREF_DATA,
"", ENTRY));
}
YangType type = (YangType) typeData;
type.setDataTypeExtendedInfo(leafRef);
// Setting by default the value of require-instance as true.
leafRef.setRequireInstance(true);
Parsable tmpData = listener.getParsedDataStack().peek();
switch (tmpData.getYangConstructType()) {
case LEAF_DATA:
// Parent YANG node of leaf to be added in resolution information.
YangLeaf leaf = (YangLeaf) listener.getParsedDataStack().pop();
Parsable parentNodeOfLeaf = listener.getParsedDataStack().peek();
listener.getParsedDataStack().push(leaf);
// Verify parent node of leaf.
if (!(parentNodeOfLeaf instanceof YangNode)) {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LEAFREF_DATA,
"", ENTRY));
}
leafRef.setResolvableStatus(UNRESOLVED);
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
(YangNode) parentNodeOfLeaf, errorLine, errorPosition);
addToResolutionList(resolutionInfo);
break;
case LEAF_LIST_DATA:
// Parent YANG node of leaf-list to be added in resolution information.
YangLeafList leafList = (YangLeafList) listener.getParsedDataStack().pop();
Parsable parentNodeOfLeafList = listener.getParsedDataStack().peek();
listener.getParsedDataStack().push(leafList);
// Verify parent node of leaf-list.
if (!(parentNodeOfLeafList instanceof YangNode)) {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LEAFREF_DATA,
"", ENTRY));
}
leafRef.setResolvableStatus(UNRESOLVED);
// Add resolution information to the list.
YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
(YangNode) parentNodeOfLeafList, errorLine, errorPosition);
addToResolutionList(resolutionInfoImpl);
break;
case TYPEDEF_DATA:
/*
* Do not add the leaf ref to resolution list. It needs to be
* added to resolution list, when leaf/leaf list references to
* this typedef. At this time that leaf/leaf-list becomes the
* parent for the leafref.
*/
break;
default:
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LEAFREF_DATA,
"", ENTRY));
}
listener.getParsedDataStack().push(typeData);
listener.getParsedDataStack().push(leafRef);
}
/**
* It is called when parser exits from grammar rule (leafref), it performs
* validation and updates the data model tree.
*
* @param listener listener's object
* @param ctx context object of the grammar rule
*/
public static void processLeafrefExit(TreeWalkListener listener,
GeneratedYangParser.LeafrefSpecificationContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_CURRENT_HOLDER, LEAFREF_DATA, "", EXIT);
Parsable parsableType = listener.getParsedDataStack().pop();
if (!(parsableType instanceof YangLeafRef)) {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LEAFREF_DATA,
"", EXIT));
}
}
/**
* Adds to resolution list.
*
* @param resolutionInfo resolution information
*/
private static void addToResolutionList(YangResolutionInfoImpl resolutionInfo) {
try {
addResolutionInfo(resolutionInfo);
} catch (DataModelException e) {
throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
LEAFREF_DATA, "", ENTRY, e.getMessage()));
}
}
}
......@@ -128,6 +128,8 @@ public final class ModuleListener {
.peek()).resolveSelfFileLinking(ResolvableType.YANG_USES);
((YangReferenceResolver) listener.getParsedDataStack()
.peek()).resolveSelfFileLinking(ResolvableType.YANG_DERIVED_DATA_TYPE);
((YangReferenceResolver) listener.getParsedDataStack()
.peek()).resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
} catch (DataModelException e) {
LinkerException linkerException = new LinkerException(e.getMessage());
linkerException.setLine(e.getLineNumber());
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.validatePathArgument;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.datamodel.utils.YangConstructType.PATH_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
/*
* Reference: RFC6020 and YANG ANTLR Grammar
*
* ABNF grammar as per RFC6020
* leafref-specification =
* ;; these stmts can appear in any order
* path-stmt stmtsep
* [require-instance-stmt stmtsep]
*
* path-stmt = path-keyword sep path-arg-str stmtend
*
* ANTLR grammar rule
*
* leafrefSpecification : (pathStatement (requireInstanceStatement)?) | ((requireInstanceStatement)? pathStatement);
*
* pathStatement : PATH_KEYWORD path STMTEND;
*/
/**
* Represents listener based call back function corresponding to the
* "path" rule defined in ANTLR grammar file for corresponding ABNF rule
* in RFC 6020.
*/
public final class PathListener {
/**
* Creates a new path listener.
*/
private PathListener() {
}
/**
* It is called when parser receives an input matching the grammar rule
* (path), performs validation and updates the data model tree.
*
* @param listener listener's object
* @param ctx context object of the grammar rule
*/
public static void processPathEntry(TreeWalkListener listener,
GeneratedYangParser.PathStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, PATH_DATA, ctx.path().getText(), ENTRY);
Parsable curData = listener.getParsedDataStack().peek();
// Checks the holder of path as leafref, else throws error.
if (curData instanceof YangLeafRef) {
// Splitting the path argument and updating it in the datamodel tree.
validatePathArgument(ctx.path().getText(), PATH_DATA, ctx, (YangLeafRef) curData);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, PATH_DATA,
ctx.path().getText(), ENTRY));
}
}
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import static org.onosproject.yangutils.datamodel.utils.YangConstructType.REQUIRE_INSTANCE_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidBooleanValue;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
/*
* Reference: RFC6020 and YANG ANTLR Grammar
*
* ABNF grammar as per RFC6020
* require-instance-stmt = require-instance-keyword sep
* require-instance-arg-str stmtend
*
* require-instance-arg-str = < a string that matches the rule
* require-instance-arg >
*
* require-instance-arg = true-keyword / false-keyword
*
* ANTLR grammar rule
*
* requireInstanceStatement : REQUIRE_INSTANCE_KEYWORD requireInstance STMTEND;
*
* requireInstance : string;
*/
/**
* Represents listener based call back function corresponding to the
* "require-instance" rule defined in ANTLR grammar file for corresponding ABNF rule
* in RFC 6020.
*/
public final class RequireInstanceListener {
/**
* Creates a new require instance listener.
*/
private RequireInstanceListener() {
}
/**
* It is called when parser receives an input matching the grammar rule
* (require-instance), performs validation and updates the data model tree.
*
* @param listener listener's object
* @param ctx context object of the grammar rule
*/
public static void processRequireInstanceEntry(TreeWalkListener listener,
GeneratedYangParser.RequireInstanceStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, REQUIRE_INSTANCE_DATA, "", ENTRY);
Parsable curData = listener.getParsedDataStack().peek();
// Gets the status of require instance
boolean isRequireInstance = getValidBooleanValue(ctx.requireInstance().getText(), REQUIRE_INSTANCE_DATA, ctx);
// Checks the holder of require-instance as leafref or type, else throws error.
if (curData instanceof YangLeafRef) {
// Sets the require-instance status to leafref.
((YangLeafRef) curData).setRequireInstance(isRequireInstance);
} else if (curData instanceof YangType) {
// Checks type should be instance-identifier, else throw error.
if (((YangType) curData).getDataType() == YangDataTypes.INSTANCE_IDENTIFIER) {
// Sets the require-instance status to instance-identifier type.
((YangType) curData).setDataTypeExtendedInfo(isRequireInstance);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, REQUIRE_INSTANCE_DATA,
ctx.getText(), ENTRY));
}
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, REQUIRE_INSTANCE_DATA,
ctx.getText(), ENTRY));
}
}
}
......@@ -133,6 +133,8 @@ public final class SubModuleListener {
.resolveSelfFileLinking(ResolvableType.YANG_USES);
((YangReferenceResolver) listener.getParsedDataStack().peek())
.resolveSelfFileLinking(ResolvableType.YANG_DERIVED_DATA_TYPE);
((YangReferenceResolver) listener.getParsedDataStack().peek())
.resolveSelfFileLinking(ResolvableType.YANG_LEAFREF);
} catch (DataModelException e) {
LinkerException linkerException = new LinkerException(e.getMessage());
linkerException.setLine(e.getLineNumber());
......
......@@ -101,6 +101,9 @@ public final class TypeListener {
type.setNodeIdentifier(nodeIdentifier);
type.setDataType(yangDataTypes);
// Set default require instance value as true for instance identifier.
setDefaultRequireInstanceForInstanceIdentifier(type);
int errorLine = ctx.getStart().getLine();
int errorPosition = ctx.getStart().getCharPositionInLine();
......@@ -233,6 +236,18 @@ public final class TypeListener {
}
/**
* Sets the default require instance value as true when the type is instance identifier.
*
* @param type type to which the value has to be set
*/
private static void setDefaultRequireInstanceForInstanceIdentifier(YangType<?> type) {
if (type.getDataType() == YangDataTypes.INSTANCE_IDENTIFIER) {
((YangType<Boolean>) type).setDataTypeExtendedInfo(true);
}
}
/**
* It is called when parser exits from grammar rule (type), it perform
* validations and update the data model tree.
*
......@@ -291,7 +306,11 @@ public final class TypeListener {
parserException = new ParserException("YANG file error : a type bits" +
" must have atleast one bit statement.");
break;
// TODO : decimal64, identity ref, leafref
case LEAFREF:
parserException = new ParserException("YANG file error : a type leafref" +
" must have one path statement.");
break;
// TODO : decimal64, identity ref
default:
return;
}
......
......@@ -18,28 +18,44 @@ package org.onosproject.yangutils.parser.impl.parserutils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import org.antlr.v4.runtime.ParserRuleContext;
import org.onosproject.yangutils.datamodel.YangAtomicPath;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
import org.onosproject.yangutils.datamodel.YangPathPredicate;
import org.onosproject.yangutils.datamodel.YangRelativePath;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import static org.onosproject.yangutils.datamodel.YangPathArgType.ABSOLUTE_PATH;
import static org.onosproject.yangutils.datamodel.YangPathArgType.RELATIVE_PATH;
import static org.onosproject.yangutils.datamodel.YangPathOperator.EQUALTO;
import static org.onosproject.yangutils.utils.UtilConstants.ADD;
import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR_ACCESSOR;
import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR_ACCESSOR_IN_PATH;
import static org.onosproject.yangutils.utils.UtilConstants.CARET;
import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_CLOSE_SQUARE_BRACKET;
import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_OPEN_SQUARE_BRACKET;
import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_SLASH;
import static org.onosproject.yangutils.utils.UtilConstants.CLOSE_PARENTHESIS;
import static org.onosproject.yangutils.utils.UtilConstants.COLON;
import static org.onosproject.yangutils.utils.UtilConstants.CURRENT;
import static org.onosproject.yangutils.utils.UtilConstants.CURRENTLY_UNSUPPORTED;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.FALSE;
import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
import static org.onosproject.yangutils.utils.UtilConstants.INSTANCE_IDENTIFIER;
import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
import static org.onosproject.yangutils.utils.UtilConstants.OPEN_SQUARE_BRACKET;
import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
import static org.onosproject.yangutils.utils.UtilConstants.YANG_FILE_ERROR;
......@@ -52,6 +68,7 @@ public final class ListenerUtil {
private static final String DATE_PATTERN = "[0-9]{4}-([0-9]{2}|[0-9])-([0-9]{2}|[0-9])";
private static final String NON_NEGATIVE_INTEGER_PATTERN = "[0-9]+";
private static final Pattern INTEGER_PATTERN = Pattern.compile("[-][0-9]+|[0-9]+");
private static final Pattern PATH_PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
private static final String XML = "xml";
private static final String ONE = "1";
private static final int IDENTIFIER_LENGTH = 64;
......@@ -115,6 +132,42 @@ public final class ListenerUtil {
}
/**
* Validates identifier and returns concatenated string if string contains plus symbol.
*
* @param identifier string from yang file
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangLeafRef instance of leafref where the path argument has to be set
* @return concatenated string after removing double quotes
*/
public static String getValidIdentifierForLeafref(String identifier, YangConstructType yangConstruct,
ParserRuleContext ctx, YangLeafRef yangLeafRef) {
String identifierString = removeQuotesAndHandleConcat(identifier);
ParserException parserException;
if (identifierString.length() > IDENTIFIER_LENGTH) {
parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() + " is " +
"greater than 64 characters.");
} else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() + " is not " +
"valid.");
} else if (identifierString.toLowerCase().startsWith(XML)) {
parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
" must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
} else {
return identifierString;
}
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
/**
* Validates the revision date.
*
* @param dateToValidate input revision date
......@@ -307,6 +360,352 @@ public final class ListenerUtil {
}
/**
* Checks and return valid node identifier specific to nodes in leafref path.
*
* @param nodeIdentifierString string from yang file
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangLeafRef instance of leafref where the path argument has to be set
* @return valid node identifier
*/
public static YangNodeIdentifier getValidNodeIdentifierForLeafref(String nodeIdentifierString,
YangConstructType yangConstruct, ParserRuleContext ctx, YangLeafRef yangLeafRef) {
String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
if (tmpData.length == 1) {
YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
checkForUnsupportedTypes(tmpData[0], yangConstruct, ctx);
nodeIdentifier.setName(getValidIdentifierForLeafref(tmpData[0], yangConstruct, ctx, yangLeafRef));
return nodeIdentifier;
} else if (tmpData.length == 2) {
YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
nodeIdentifier.setPrefix(getValidIdentifierForLeafref(tmpData[0], yangConstruct, ctx, yangLeafRef));
nodeIdentifier.setName(getValidIdentifierForLeafref(tmpData[1], yangConstruct, ctx, yangLeafRef));
return nodeIdentifier;
} else {
ParserException parserException = new ParserException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
" is not valid.");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
}
/**
* Validates the path argument. It can be either absolute or relative path.
*
* @param pathString the path string from the path type
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangLeafRef instance of leafref where the path argument has to be set
*/
public static void validatePathArgument(String pathString, YangConstructType yangConstruct,
ParserRuleContext ctx, YangLeafRef yangLeafRef) {
String completePathString = removeQuotesAndHandleConcat(pathString);
yangLeafRef.setPath(completePathString);
if (completePathString.startsWith(SLASH)) {
yangLeafRef.setPathType(ABSOLUTE_PATH);
List<YangAtomicPath> yangAtomicPathListList = validateAbsolutePath(completePathString, yangConstruct, ctx,
yangLeafRef);
yangLeafRef.setAtomicPath(yangAtomicPathListList);
} else if (completePathString.startsWith(ANCESTOR_ACCESSOR)) {
yangLeafRef.setPathType(RELATIVE_PATH);
validateRelativePath(completePathString, yangConstruct, ctx, yangLeafRef);
} else {
ParserException parserException = new ParserException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
" does not follow valid path syntax");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
}
/**
* Validates the relative path.
*
* @param completePathString the path string of relative path
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangLeafRef instance of leafref where the path argument has to be set
*/
private static void validateRelativePath(String completePathString, YangConstructType yangConstruct,
ParserRuleContext ctx, YangLeafRef yangLeafRef) {
YangRelativePath relativePath = new YangRelativePath();
int numberOfAncestors = 0;
while (completePathString.startsWith(ANCESTOR_ACCESSOR_IN_PATH)) {
completePathString = completePathString.replaceFirst(ANCESTOR_ACCESSOR_IN_PATH, EMPTY_STRING);
numberOfAncestors = numberOfAncestors + 1;
}
if (completePathString == null || completePathString.length() == 0) {
ParserException parserException = new ParserException("YANG file error : "
+ YangConstructType.getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
" does not follow valid path syntax");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
relativePath.setAncestorNodeCount(numberOfAncestors);
List<YangAtomicPath> atomicPath = validateAbsolutePath(SLASH_FOR_STRING + completePathString,
yangConstruct,
ctx, yangLeafRef);
relativePath.setAtomicPathList(atomicPath);
yangLeafRef.setRelativePath(relativePath);
}
/**
* Validates the absolute path.
*
* @param completePathString the path string of absolute path
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangLeafRef instance of leafref where the path argument has to be set
* @return list of object of node in absolute path
*/
private static List<YangAtomicPath> validateAbsolutePath(String completePathString,
YangConstructType yangConstruct, ParserRuleContext ctx, YangLeafRef yangLeafRef) {
List<YangAtomicPath> absolutePathList = new LinkedList<>();
YangPathPredicate yangPathPredicate = new YangPathPredicate();
YangNodeIdentifier yangNodeIdentifier;
while (completePathString != null) {
String path = completePathString.replaceFirst(SLASH_FOR_STRING, EMPTY_STRING);
if (path == null || path.length() == 0) {
ParserException parserException = new ParserException("YANG file error : "
+ YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
" does not follow valid path syntax");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
String matchedPathPredicate;
String nodeIdentifier;
String[] differentiate = new String[2];
int forNodeIdentifier = path.indexOf(CHAR_OF_SLASH);
int forPathPredicate = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
// Checks if path predicate is present for the node.
if ((forPathPredicate < forNodeIdentifier) && (forPathPredicate != -1)) {
List<String> pathPredicate = new ArrayList<>();
matchedPathPredicate = matchForPathPredicate(path);
if (matchedPathPredicate == null || matchedPathPredicate.length() == 0) {
ParserException parserException = new ParserException("YANG file error : "
+ YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
" does not follow valid path syntax");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
int indexOfMatchedFirstOpenBrace = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
differentiate[0] = path.substring(0, indexOfMatchedFirstOpenBrace);
differentiate[1] = path.substring(indexOfMatchedFirstOpenBrace);
pathPredicate.add(matchedPathPredicate);
nodeIdentifier = differentiate[0];
// Starts adding all path predicates of a node into the list.
if (!differentiate[1].isEmpty()) {
while (differentiate[1].startsWith(OPEN_SQUARE_BRACKET)) {
matchedPathPredicate = matchForPathPredicate(differentiate[1]);
if (matchedPathPredicate == null || matchedPathPredicate.length() == 0) {
ParserException parserException = new ParserException(
"YANG file error : " + YangConstructType.getYangConstructType(yangConstruct) + " "
+ yangLeafRef.getPath() +
" does not follow valid path syntax");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
pathPredicate.add(matchedPathPredicate);
differentiate[1] = differentiate[1].substring(matchedPathPredicate.length());
}
}
List<YangPathPredicate> pathPredicateList = validatePathPredicate(pathPredicate, yangConstruct, ctx,
yangPathPredicate, yangLeafRef);
YangAtomicPath atomicPath = new YangAtomicPath();
yangNodeIdentifier = getValidNodeIdentifierForLeafref(nodeIdentifier, yangConstruct, ctx, yangLeafRef);
atomicPath.setNodeIdentifier(yangNodeIdentifier);
atomicPath.setPathPredicatesList(pathPredicateList);
absolutePathList.add(atomicPath);
} else {
if (path.contains(SLASH_FOR_STRING)) {
nodeIdentifier = path.substring(0, path.indexOf(CHAR_OF_SLASH));
differentiate[1] = path.substring(path.indexOf(CHAR_OF_SLASH));
} else {
nodeIdentifier = path;
differentiate[1] = null;
}
yangNodeIdentifier = getValidNodeIdentifierForLeafref(nodeIdentifier, yangConstruct, ctx, yangLeafRef);
YangAtomicPath atomicPath = new YangAtomicPath();
atomicPath.setNodeIdentifier(yangNodeIdentifier);
atomicPath.setPathPredicatesList(null);
absolutePathList.add(atomicPath);
}
if (differentiate[1] == null || differentiate[1].length() == 0) {
completePathString = null;
} else {
completePathString = differentiate[1];
}
}
return absolutePathList;
}
/**
* Validates path predicate in the absolute path's node.
*
* @param pathPredicate list of path predicates in the node of absolute path
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangPathPredicate instance of path predicate where it has to be set
* @param yangLeafRef instance of leafref where the path argument has to be set
* @return list of object of path predicates in absolute path's node
*/
private static List<YangPathPredicate> validatePathPredicate(List<String> pathPredicate,
YangConstructType yangConstruct, ParserRuleContext ctx, YangPathPredicate yangPathPredicate,
YangLeafRef yangLeafRef) {
Iterator<String> pathPredicateString = pathPredicate.iterator();
List<String> pathEqualityExpression = new ArrayList<>();
while (pathPredicateString.hasNext()) {
String pathPredicateForNode = pathPredicateString.next();
pathPredicateForNode = (pathPredicateForNode.substring(1)).trim();
pathPredicateForNode = pathPredicateForNode.substring(0,
pathPredicateForNode.indexOf(CHAR_OF_CLOSE_SQUARE_BRACKET));
pathEqualityExpression.add(pathPredicateForNode);
}
List<YangPathPredicate> validatedPathPredicateList = validatePathEqualityExpression(pathEqualityExpression,
yangConstruct, ctx, yangPathPredicate, yangLeafRef);
return validatedPathPredicateList;
}
/**
* Validates the path equality expression.
*
* @param pathEqualityExpression list of path equality expression in the path predicates of the node
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangPathPredicate instance of path predicate where it has to be set
* @param yangLeafRef instance of leafref where the path argument has to be set
* @return list of object of path predicates in absolute path's node
*/
private static List<YangPathPredicate> validatePathEqualityExpression(List<String> pathEqualityExpression,
YangConstructType yangConstruct, ParserRuleContext ctx, YangPathPredicate yangPathPredicate,
YangLeafRef yangLeafRef) {
Iterator<String> pathEqualityExpressionString = pathEqualityExpression.iterator();
List<YangPathPredicate> yangPathPredicateList = new ArrayList<>();
while (pathEqualityExpressionString.hasNext()) {
String pathEqualityExpressionForNode = pathEqualityExpressionString.next();
String[] pathEqualityExpressionArray = pathEqualityExpressionForNode.split("[=]");
YangNodeIdentifier yangNodeIdentifierForPredicate;
YangRelativePath yangRelativePath;
yangNodeIdentifierForPredicate = getValidNodeIdentifierForLeafref(pathEqualityExpressionArray[0].trim(),
yangConstruct, ctx, yangLeafRef);
yangRelativePath = validatePathKeyExpression(pathEqualityExpressionArray[1].trim(), yangConstruct, ctx,
yangLeafRef);
yangPathPredicate.setNodeIdentifier(yangNodeIdentifierForPredicate);
yangPathPredicate.setPathOperator(EQUALTO);
yangPathPredicate.setRightRelativePath(yangRelativePath);
yangPathPredicateList.add(yangPathPredicate);
}
return yangPathPredicateList;
}
/**
* Validate the path key expression.
*
* @param rightRelativePath relative path in the path predicate
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangLeafRef instance of leafref where the path argument has to be set
* @return object of right relative path in path predicate
*/
private static YangRelativePath validatePathKeyExpression(String rightRelativePath,
YangConstructType yangConstruct, ParserRuleContext ctx, YangLeafRef yangLeafRef) {
YangRelativePath yangRelativePath = new YangRelativePath();
String[] relativePath = rightRelativePath.split(SLASH_FOR_STRING);
List<String> rightAbsolutePath = new ArrayList<>();
int accessAncestor = 0;
for (String path : relativePath) {
if (path.trim().equals(ANCESTOR_ACCESSOR)) {
accessAncestor = accessAncestor + 1;
} else {
rightAbsolutePath.add(path);
}
}
List<YangAtomicPath> atomicPathInRelativePath = validateRelativePathKeyExpression(rightAbsolutePath,
yangConstruct, ctx, yangLeafRef);
yangRelativePath.setAtomicPathList(atomicPathInRelativePath);
yangRelativePath.setAncestorNodeCount(accessAncestor);
return yangRelativePath;
}
/**
* Validates the relative path key expression.
*
* @param rightAbsolutePath absolute path nodes present in the relative path
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param yangLeafRef instance of leafref where the path argument has to be set
* @return list of object of absolute path nodes present in the relative path
*/
private static List<YangAtomicPath> validateRelativePathKeyExpression(List<String> rightAbsolutePath,
YangConstructType yangConstruct, ParserRuleContext ctx, YangLeafRef yangLeafRef) {
List<YangAtomicPath> atomicPathList = new ArrayList<>();
YangNodeIdentifier yangNodeIdentifier;
Iterator<String> nodes = rightAbsolutePath.iterator();
String currentInvocationFunction = nodes.next();
currentInvocationFunction = currentInvocationFunction.trim();
String[] currentFunction = currentInvocationFunction.split("[(]");
if (!(currentFunction[0].trim().equals(CURRENT)) || !(currentFunction[1].trim().equals(CLOSE_PARENTHESIS))) {
ParserException parserException = new ParserException("YANG file error : "
+ YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
" does not follow valid path syntax");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
while (nodes.hasNext()) {
YangAtomicPath atomicPath = new YangAtomicPath();
String node = nodes.next();
yangNodeIdentifier = getValidNodeIdentifierForLeafref(node.trim(), yangConstruct, ctx, yangLeafRef);
atomicPath.setNodeIdentifier(yangNodeIdentifier);
atomicPathList.add(atomicPath);
}
return atomicPathList;
}
/**
* Validates the match for first path predicate in a given string.
*
* @param matchRequiredString string for which match has to be done
* @return the matched string
*/
private static String matchForPathPredicate(String matchRequiredString) {
String matchedString = null;
java.util.regex.Matcher matcher = PATH_PREDICATE_PATTERN.matcher(matchRequiredString);
if (matcher.find()) {
matchedString = matcher.group(0);
}
return matchedString;
}
/**
* Checks whether the type is an unsupported type.
*
* @param typeName name of the type
......@@ -317,15 +716,9 @@ public final class ListenerUtil {
YangConstructType yangConstruct, ParserRuleContext ctx) {
if (yangConstruct == YangConstructType.TYPE_DATA) {
if (typeName.equalsIgnoreCase(LEAFREF)) {
handleUnsupportedYangConstruct(YangConstructType.LEAFREF_DATA,
ctx, CURRENTLY_UNSUPPORTED);
} else if (typeName.equalsIgnoreCase(IDENTITYREF)) {
if (typeName.equalsIgnoreCase(IDENTITYREF)) {
handleUnsupportedYangConstruct(YangConstructType.IDENTITYREF_DATA,
ctx, CURRENTLY_UNSUPPORTED);
} else if (typeName.equalsIgnoreCase(INSTANCE_IDENTIFIER)) {
handleUnsupportedYangConstruct(YangConstructType.INSTANCE_IDENTIFIER_DATA,
ctx, CURRENTLY_UNSUPPORTED);
}
}
}
......
......@@ -19,6 +19,8 @@ package org.onosproject.yangutils.translator.tojava;
import java.io.IOException;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.translator.exception.TranslatorException;
import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
......@@ -80,7 +82,20 @@ public final class JavaCodeGeneratorUtil {
if (!(codeGenNode instanceof JavaCodeGenerator)) {
throw new TranslatorException("Unsupported node to generate code");
}
if (codeGenNode instanceof YangTypeDef) {
YangTypeDef typeDef = (YangTypeDef) codeGenNode;
if (typeDef.getTypeDefBaseType().getDataType() == YangDataTypes.LEAFREF
|| typeDef.getTypeDefBaseType().getDataType() == YangDataTypes.IDENTITYREF) {
if (codeGenNode.getNextSibling() != null) {
curTraversal = SIBILING;
codeGenNode = codeGenNode.getNextSibling();
} else {
curTraversal = PARENT;
codeGenNode = codeGenNode.getParent();
}
continue;
}
}
setCurNode(codeGenNode);
try {
generateCodeEntry(codeGenNode, yangPlugin);
......
......@@ -17,13 +17,15 @@
package org.onosproject.yangutils.translator.tojava.javamodel;
import java.util.Stack;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangDerivedInfo;
import org.onosproject.yangutils.datamodel.YangEnumeration;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.YangUnion;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.translator.exception.TranslatorException;
import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
import org.onosproject.yangutils.translator.tojava.JavaFileInfo;
......@@ -101,6 +103,10 @@ public final class AttributesJavaDataType {
return STRING_DATA_TYPE;
case BOOLEAN:
return BOOLEAN_DATA_TYPE;
case INSTANCE_IDENTIFIER:
return STRING_DATA_TYPE;
case LEAFREF:
return getJavaDataType(getReferredTypeFromLeafref(yangType));
default:
throw new TranslatorException("given data type is not supported.");
}
......@@ -152,8 +158,8 @@ public final class AttributesJavaDataType {
case BINARY:
return YANG_BINARY_CLASS;
case LEAFREF:
//TODO:LEAFREF
break;
YangType<?> referredType = getReferredTypeFromLeafref(yangType);
return getJavaImportClass(referredType, isListAttr, pluginConfig);
case IDENTITYREF:
//TODO:IDENTITYREF
break;
......@@ -163,8 +169,7 @@ public final class AttributesJavaDataType {
return getCapitalCase(getCamelCase(((YangJavaUnion) yangType.getDataTypeExtendedInfo()).getName(),
pluginConfig));
case INSTANCE_IDENTIFIER:
//TODO:INSTANCE_IDENTIFIER
break;
return STRING_DATA_TYPE;
case DERIVED:
return getCapitalCase(
getCamelCase(yangType.getDataTypeName(), pluginConfig));
......@@ -188,8 +193,8 @@ public final class AttributesJavaDataType {
case BINARY:
return YANG_BINARY_CLASS;
case LEAFREF:
//TODO:LEAFREF
break;
YangType<?> referredType = getReferredTypeFromLeafref(yangType);
return getJavaImportClass(referredType, isListAttr, pluginConfig);
case IDENTITYREF:
//TODO:IDENTITYREF
break;
......@@ -199,8 +204,7 @@ public final class AttributesJavaDataType {
return getCapitalCase(getCamelCase(((YangJavaUnion) yangType.getDataTypeExtendedInfo()).getName(),
pluginConfig));
case INSTANCE_IDENTIFIER:
//TODO:INSTANCE_IDENTIFIER
break;
return STRING_DATA_TYPE;
case DERIVED:
return getCapitalCase(
getCamelCase(yangType.getDataTypeName(), pluginConfig));
......@@ -246,16 +250,15 @@ public final class AttributesJavaDataType {
case BINARY:
return YANG_TYPES_PKG;
case LEAFREF:
//TODO:LEAFREF
break;
YangType<?> referredType = getReferredTypeFromLeafref(yangType);
return getJavaImportPackage(referredType, isListAttr, conflictResolver);
case IDENTITYREF:
//TODO:IDENTITYREF
break;
case UNION:
return getUnionPackage(yangType, conflictResolver);
case INSTANCE_IDENTIFIER:
//TODO:INSTANCE_IDENTIFIER
break;
return JAVA_LANG;
case DERIVED:
return getTypDefsPackage(yangType, conflictResolver);
default:
......@@ -274,8 +277,8 @@ public final class AttributesJavaDataType {
case BINARY:
return YANG_TYPES_PKG;
case LEAFREF:
//TODO:LEAFREF
break;
YangType<?> referredType = getReferredTypeFromLeafref(yangType);
return getJavaImportPackage(referredType, isListAttr, conflictResolver);
case IDENTITYREF:
//TODO:IDENTITYREF
break;
......@@ -284,8 +287,7 @@ public final class AttributesJavaDataType {
case UNION:
return getUnionPackage(yangType, conflictResolver);
case INSTANCE_IDENTIFIER:
//TODO:INSTANCE_IDENTIFIER
break;
return JAVA_LANG;
case DERIVED:
return getTypDefsPackage(yangType, conflictResolver);
default:
......@@ -444,4 +446,15 @@ public final class AttributesJavaDataType {
.getPackage()));
}
}
/**
* Returns the referred type from leaf/leaf-list.
*
* @param type current type in leaf
* @return type from the leafref
*/
private static YangType<?> getReferredTypeFromLeafref(YangType type) {
YangLeafRef<?> leafRefInfo = (YangLeafRef<?>) type.getDataTypeExtendedInfo();
return leafRefInfo.getEffectiveDataType();
}
}
......
......@@ -18,8 +18,9 @@ package org.onosproject.yangutils.translator.tojava.utils;
import java.util.List;
import java.util.Map;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.translator.exception.TranslatorException;
import org.onosproject.yangutils.translator.tojava.JavaAttributeInfo;
import org.onosproject.yangutils.utils.io.impl.JavaDocGen;
......@@ -118,6 +119,7 @@ import static org.onosproject.yangutils.utils.UtilConstants.TWELVE_SPACE_INDENTA
import static org.onosproject.yangutils.utils.UtilConstants.VALUE;
import static org.onosproject.yangutils.utils.UtilConstants.VOID;
import static org.onosproject.yangutils.utils.UtilConstants.YANG_UTILS_TODO;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.getJavaDoc;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.BUILD_METHOD;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.CONSTRUCTOR;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.DEFAULT_CONSTRUCTOR;
......@@ -127,7 +129,6 @@ import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.MAN
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.OF_METHOD;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.SETTER_METHOD;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.TYPE_CONSTRUCTOR;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.getJavaDoc;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCamelCase;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getSmallCase;
......
......@@ -282,6 +282,16 @@ public final class UtilConstants {
public static final String INPUT = "input";
/**
* Static attribute for output string.
*/
public static final String OUTPUT = "output";
/**
* Static attribute for current string.
*/
public static final String CURRENT = "current";
/**
* Static attribute for leafref string.
*/
public static final String LEAFREF = "leafref";
......@@ -342,6 +352,41 @@ public final class UtilConstants {
public static final String COMMA = ",";
/**
* Static attribute for slash character.
*/
public static final char CHAR_OF_SLASH = '/';
/**
* Static attribute for open square bracket character.
*/
public static final char CHAR_OF_OPEN_SQUARE_BRACKET = '[';
/**
* Static attribute for close square bracket character.
*/
public static final char CHAR_OF_CLOSE_SQUARE_BRACKET = ']';
/**
* Static attribute for slash string.
*/
public static final String SLASH_FOR_STRING = "/";
/**
* Static attribute for open square bracket.
*/
public static final String OPEN_SQUARE_BRACKET = "[";
/**
* Static attribute for ancestor accessor.
*/
public static final String ANCESTOR_ACCESSOR = "..";
/**
* Static attribute for ancestor accessor along with path.
*/
public static final String ANCESTOR_ACCESSOR_IN_PATH = "../";
/**
* Static attribute for add syntax.
*/
public static final String ADD_STRING = "add";
......@@ -1110,7 +1155,6 @@ public final class UtilConstants {
*/
public static final String YANG_DECIMAL64_CLASS = "YangDecimal64";
/**
* Static attribute for YANG file error.
*/
......@@ -1140,12 +1184,18 @@ public final class UtilConstants {
+ "grouping for given uses";
/**
* Static attribute for grouping linker error information.
* Static attribute for if-feature linker error information.
*/
public static final String FEATURE_LINKER_ERROR = "YANG file error: Unable to find feature "
+ "for given if-feature";
/**
* Static attribute for leafref linker error information.
*/
public static final String LEAFREF_LINKER_ERROR = "YANG file error: Unable to find base "
+ "leaf/leaf-list for given leafref";
/**
* Static attribute for reference.
*/
public static final String REFERENCE = "Reference";
......
......@@ -534,7 +534,7 @@ package org.onosproject.yangutils.parser.antlrgencode;
* require-instance-arg >
* require-instance-arg = true-keyword / false-keyword
*/
requireInstanceStatement : REQUIRE_INSTANCE_KEYWORD (TRUE_KEYWORD | FALSE_KEYWORD) STMTEND;
requireInstanceStatement : REQUIRE_INSTANCE_KEYWORD requireInstance STMTEND;
/**
* instance-identifier-specification =
......@@ -1279,6 +1279,8 @@ package org.onosproject.yangutils.parser.antlrgencode;
refine : string;
requireInstance : string;
augment : string;
deviation : string;
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.parser.impl.listeners;
import java.io.IOException;
import java.util.ListIterator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
/**
* Test cases for require-instance listener.
*/
public class RequireInstanceListenerTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks require-statement with true as status.
*/
@Test
public void processRequireInstanceTrue() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/RequireInstanceTrue.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("PathListener"));
YangContainer container = (YangContainer) yangNode.getChild().getNextSibling();
ListIterator<YangLeaf> leafIterator = container.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// Check whether the require-instance value is set correctly in leafref.
assertThat(leafInfo.getName(), is("ifname"));
YangLeafRef yangLeafRef = (YangLeafRef) leafInfo.getDataType().getDataTypeExtendedInfo();
assertThat(yangLeafRef.getRequireInstance(), is(true));
}
/**
* Checks require-statement with false as status.
*/
@Test
public void processRequireInstanceFalse() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/RequireInstanceFalse.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("PathListener"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// Check whether the require-instance value is set correctly in instance-identifier.
assertThat(leafInfo.getName(), is("admin-status"));
YangType type = leafInfo.getDataType();
assertThat(type.getDataType(), is(YangDataTypes.INSTANCE_IDENTIFIER));
boolean status = ((YangType<Boolean>) type).getDataTypeExtendedInfo();
assertThat(status, is(false));
}
/**
* Checks require-statement default value when its not there in YANG under instance-identifier.
*/
@Test
public void processRequireInstanceDefaultValueInInstanceIdentifier() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/RequireInstanceDefaultValueInInstanceIdentifier.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("PathListener"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// Check whether the require-instance value is set correctly in instance-identifier.
assertThat(leafInfo.getName(), is("admin-status"));
YangType type = leafInfo.getDataType();
assertThat(type.getDataType(), is(YangDataTypes.INSTANCE_IDENTIFIER));
boolean status = ((YangType<Boolean>) type).getDataTypeExtendedInfo();
assertThat(status, is(true));
}
/**
* Checks require-statement default value when its not there in YANG under leafref.
*/
@Test
public void processRequireInstanceDefaultValueForLeafref() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/RequireInstanceDefaultValueForLeafref.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("PathListener"));
YangContainer container = (YangContainer) yangNode.getChild().getNextSibling();
ListIterator<YangLeaf> leafIterator = container.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// Check whether the require-instance value is set correctly in leafref.
assertThat(leafInfo.getName(), is("ifname"));
YangLeafRef yangLeafRef = (YangLeafRef) leafInfo.getDataType().getDataTypeExtendedInfo();
assertThat(yangLeafRef.getRequireInstance(), is(true));
}
}
......@@ -20,6 +20,7 @@ import java.util.ListIterator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
......@@ -121,20 +122,6 @@ public class TypeListenerTest {
}
/**
* Checks for unsupported type leafref.
*/
@Test
public void processLeafrefType() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("YANG file error : \"leafref\" is not supported in current version,"
+ " please check wiki for YANG utils road map.");
YangNode node = manager
.getDataModel("src/test/resources/LeafrefInvalidIdentifier.yang");
}
/**
* Checks for unsupported type identityref.
*/
@Test
......@@ -149,16 +136,29 @@ public class TypeListenerTest {
}
/**
* Checks for unsupported type instance identifier.
* Checks for type instance-identifier.
*/
@Test
public void processInstanceIdentifierType() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("YANG file error : \"instance-identifier\" is not supported in current version,"
+ " please check wiki for YANG utils road map.");
YangNode node = manager
.getDataModel("src/test/resources/InstanceIdentifierInvalidIdentifier.yang");
.getDataModel("src/test/resources/InstanceIdentifierListener.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer container = (YangContainer) yangNode.getChild();
ListIterator<YangLeaf> leafIterator = container.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("invalid-interval"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("instance-identifier"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.INSTANCE_IDENTIFIER));
}
}
......
......@@ -20,27 +20,34 @@ import java.io.IOException;
import java.util.Iterator;
import java.util.ListIterator;
import org.apache.maven.plugin.MojoExecutionException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangDerivedInfo;
import org.onosproject.yangutils.datamodel.YangGrouping;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.YangUses;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.linker.exceptions.LinkerException;
import org.onosproject.yangutils.linker.impl.YangLinkerManager;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import org.onosproject.yangutils.utils.io.impl.YangFileScanner;
import org.onosproject.yangutils.utils.io.impl.YangPluginConfig;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DERIVED;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.STRING;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DERIVED;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.LEAFREF;
import static org.onosproject.yangutils.datamodel.YangNodeType.MODULE_NODE;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
......@@ -50,6 +57,10 @@ import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirector
*/
public class InterFileLinkingTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
private final YangUtilsParserManager manager = new YangUtilsParserManager();
private final YangUtilManager utilManager = new YangUtilManager();
private final YangLinkerManager yangLinkerManager = new YangLinkerManager();
......@@ -726,4 +737,253 @@ public class InterFileLinkingTest {
deleteDirectory(userDir + "/target/groupingNodeSameAsModule/");
}
/**
* Checks inter file leafref linking.
*/
@Test
public void processInterFileLeafrefLinking()
throws IOException, ParserException, MojoExecutionException {
String searchDir = "src/test/resources/interfileleafref";
utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
utilManager.parseYangFileInfoSet();
utilManager.createYangNodeSet();
YangNode refNode = null;
YangNode selfNode = null;
// Create YANG node set
yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
// Add references to import list.
yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
// Carry out inter-file linking.
yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
YangNode rootNode = yangNodeIterator.next();
if (rootNode.getName().equals("module1")) {
selfNode = rootNode;
refNode = yangNodeIterator.next();
} else {
refNode = rootNode;
selfNode = yangNodeIterator.next();
}
// Check whether the data model tree returned is of type module.
assertThat(selfNode instanceof YangModule, is(true));
// Check whether the node type is set properly to module.
assertThat(selfNode.getNodeType(), is(MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) selfNode;
assertThat(yangNode.getName(), is("module1"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("invalid-interval"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(LEAFREF));
// Check whether the data model tree returned is of type module.
assertThat(refNode instanceof YangModule, is(true));
// Check whether the node type is set properly to module.
assertThat(refNode.getNodeType(), is(MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode1 = (YangModule) refNode;
assertThat(yangNode1.getName(), is("module2"));
YangLeaf leafInfo1 = yangNode1.getListOfLeaf().listIterator().next();
YangLeafRef leafref = (YangLeafRef) leafInfo.getDataType().getDataTypeExtendedInfo();
assertThat(leafref.getReferredLeafOrLeafList(), is(leafInfo1));
assertThat(leafref.getResolvableStatus(), is(RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.STRING));
}
/**
* Checks error scenerio where the node is invalid.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToInvalidNode()
throws IOException, ParserException {
thrown.expect(LinkerException.class);
thrown.expectMessage(
"YANG file error: Unable to find base leaf/leaf-list for given leafref");
String searchDir = "src/test/resources/interFileInvalidNode";
utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
utilManager.parseYangFileInfoSet();
utilManager.createYangNodeSet();
YangNode selfNode = null;
// Create YANG node set
yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
// Add references to import list.
yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
// Carry out inter-file linking.
yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
}
/**
* Checks the error scenerio when there is no referref leaf/leaf-list in any file.
*/
@Test
public void processSelfResolutionWhenLeafrefDoesNotReferToLeafOrLeafList()
throws IOException, ParserException {
thrown.expect(LinkerException.class);
thrown.expectMessage(
"YANG file error: Unable to find base leaf/leaf-list for given leafref");
String searchDir = "src/test/resources/interfileleafrefwithinvaliddestinationnode";
utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
utilManager.parseYangFileInfoSet();
utilManager.createYangNodeSet();
YangNode selfNode = null;
// Create YANG node set
yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
// Add references to import list.
yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
// Carry out inter-file linking.
yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
}
/**
* Checks inter file resolution when leafref from grouping refers to other file.
*/
@Test
public void processInterFileLeafrefFromGroupingRefersToOtherFile()
throws IOException, ParserException {
String searchDir = "src/test/resources/interfileleafreffromgroupingreferstootherfile";
utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
utilManager.parseYangFileInfoSet();
utilManager.createYangNodeSet();
YangNode selfNode = null;
YangNode refNode = null;
// Create YANG node set
yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
// Add references to import list.
yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
// Carry out inter-file linking.
yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
YangNode rootNode = yangNodeIterator.next();
if (rootNode.getName().equals("module1")) {
selfNode = rootNode;
refNode = yangNodeIterator.next();
} else {
refNode = rootNode;
selfNode = yangNodeIterator.next();
}
// Check whether the data model tree returned is of type module.
assertThat(selfNode instanceof YangModule, is(true));
// Check whether the node type is set properly to module.
assertThat(selfNode.getNodeType(), is(MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) selfNode;
assertThat(yangNode.getName(), is("module1"));
YangList list = (YangList) yangNode.getChild().getChild();
ListIterator<YangLeaf> leafIterator = list.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("link-tp"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(LEAFREF));
YangLeafRef leafref = (YangLeafRef) leafInfo.getDataType().getDataTypeExtendedInfo();
YangLeaf leafInfo2 = (YangLeaf) leafref.getReferredLeafOrLeafList();
assertThat(leafref.getReferredLeafOrLeafList(), is(leafInfo2));
assertThat(leafref.getResolvableStatus(), is(RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.STRING));
}
/**
* Checks inter file resolution when leafref refers to multiple leafrefs through many files.
*/
@Test
public void processInterFileLeafrefRefersToMultipleLeafrefInMultipleFiles()
throws IOException, ParserException {
String searchDir = "src/test/resources/interfileleafrefreferstomultipleleafrefinmultiplefiles";
utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
utilManager.parseYangFileInfoSet();
utilManager.createYangNodeSet();
YangNode refNode1 = null;
YangNode refNode2 = null;
YangNode selfNode = null;
// Create YANG node set
yangLinkerManager.createYangNodeSet(utilManager.getYangNodeSet());
// Add references to import list.
yangLinkerManager.addRefToYangFilesImportList(utilManager.getYangNodeSet());
// Carry out inter-file linking.
yangLinkerManager.processInterFileLinking(utilManager.getYangNodeSet());
for (YangNode rootNode : utilManager.getYangNodeSet()) {
if (rootNode.getName().equals("ietf-network-topology")) {
selfNode = rootNode;
} else if (rootNode.getName().equals("ietf-network")) {
refNode1 = rootNode;
} else {
refNode2 = rootNode;
}
}
// Check whether the data model tree returned is of type module.
assertThat(selfNode instanceof YangModule, is(true));
// Check whether the node type is set properly to module.
assertThat(selfNode.getNodeType(), is(MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) selfNode;
assertThat(yangNode.getName(), is("ietf-network-topology"));
YangList list = (YangList) yangNode.getChild().getChild();
ListIterator<YangLeaf> leafIterator = list.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("link-tp"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(LEAFREF));
YangLeafRef leafref = (YangLeafRef) leafInfo.getDataType().getDataTypeExtendedInfo();
YangLeaf leafInfo2 = (YangLeaf) leafref.getReferredLeafOrLeafList();
assertThat(leafref.getReferredLeafOrLeafList(), is(leafInfo2));
assertThat(leafref.getResolvableStatus(), is(RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.STRING));
}
}
......
......@@ -18,11 +18,15 @@ package org.onosproject.yangutils.plugin.manager;
import java.io.IOException;
import java.util.List;
import java.util.ListIterator;
import org.junit.Test;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangFeature;
import org.onosproject.yangutils.datamodel.YangIfFeature;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
......@@ -217,4 +221,111 @@ public class IntraFileIfFeatureLinkingTest {
assertThat(ifFeature.getName().getName(), is("local-storage"));
assertThat(ifFeature.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
}
/**
* Checks addition of if-feature list to leafref.
*/
@Test
public void processSelfFileLinkingWithFeatureReferredByLeafref()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfFileLinkingWithFeatureReferredByLeafref.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("syslog"));
List<YangFeature> featureList = yangNode.getFeatureList();
YangFeature feature = featureList.iterator().next();
assertThat(feature.getName(), is("local-storage"));
YangContainer container = (YangContainer) yangNode.getChild();
assertThat(container.getName(), is("speed"));
List<YangLeaf> listOfLeaf = container.getListOfLeaf();
YangLeaf leaf = listOfLeaf.iterator().next();
assertThat(leaf.getName(), is("local-storage-limit"));
List<YangIfFeature> ifFeatureList = leaf.getIfFeatureList();
YangIfFeature ifFeature = ifFeatureList.iterator().next();
assertThat(ifFeature.getName().getName(), is("local-storage"));
assertThat(ifFeature.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
ListIterator<YangLeaf> listOfLeafInModule = yangNode.getListOfLeaf().listIterator();
YangLeaf yangLeaf = listOfLeafInModule.next();
assertThat(yangLeaf.getName(), is("storage-value"));
YangLeafRef leafRef = (YangLeafRef) yangLeaf.getDataType().getDataTypeExtendedInfo();
assertThat(leafRef.getEffectiveDataType().getDataType(), is(YangDataTypes.UINT64));
List<YangIfFeature> ifFeatureListInLeafref = leafRef.getIfFeatureList();
YangIfFeature ifFeatureInLeafref = ifFeatureListInLeafref.iterator().next();
assertThat(ifFeatureInLeafref.getName().getName(), is("local-storage"));
assertThat(ifFeatureInLeafref.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
}
/**
* Checks addition of if-feature list to leafref when referred leaf is again having leafref in it.
*/
@Test
public void processSelfFileLinkingWithFeatureReferredByMultiLeafref()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfFileLinkingWithFeatureReferredByMultiLeafref.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("syslog"));
List<YangFeature> featureList = yangNode.getFeatureList();
YangFeature feature = featureList.iterator().next();
assertThat(feature.getName(), is("local-storage"));
YangContainer container = (YangContainer) yangNode.getChild();
assertThat(container.getName(), is("speed"));
List<YangLeaf> listOfLeaf = container.getListOfLeaf();
YangLeaf leaf = listOfLeaf.iterator().next();
assertThat(leaf.getName(), is("local-storage-limit"));
List<YangIfFeature> ifFeatureList = leaf.getIfFeatureList();
YangIfFeature ifFeature = ifFeatureList.iterator().next();
assertThat(ifFeature.getName().getName(), is("local-storage"));
assertThat(ifFeature.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
ListIterator<YangLeaf> listOfLeafInModule = yangNode.getListOfLeaf().listIterator();
YangLeaf yangLeaf = listOfLeafInModule.next();
assertThat(yangLeaf.getName(), is("storage-value"));
YangLeafRef leafRef = (YangLeafRef) yangLeaf.getDataType().getDataTypeExtendedInfo();
assertThat(leafRef.getEffectiveDataType().getDataType(), is(YangDataTypes.UINT64));
List<YangIfFeature> ifFeatureListInLeafref = leafRef.getIfFeatureList();
YangIfFeature ifFeatureInLeafref = ifFeatureListInLeafref.iterator().next();
assertThat(ifFeatureInLeafref.getName().getName(), is("main-storage"));
assertThat(ifFeatureInLeafref.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
YangIfFeature ifFeatureInLeafref1 = ifFeatureListInLeafref.iterator().next();
assertThat(ifFeatureInLeafref1.getName().getName(), is("main-storage"));
assertThat(ifFeatureInLeafref1.getResolvableStatus(), is(ResolvableStatus.RESOLVED));
}
}
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.plugin.manager;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.datamodel.YangAtomicPath;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangInput;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.datamodel.YangPathArgType;
import org.onosproject.yangutils.datamodel.YangPathOperator;
import org.onosproject.yangutils.datamodel.YangPathPredicate;
import org.onosproject.yangutils.datamodel.YangRelativePath;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.linker.exceptions.LinkerException;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.nullValue;
/**
* Test cases for testing leafref intra file linking.
*/
public class IntraFileLeafrefLinkingTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks self resolution when leafref under module refers to leaf in container.
*/
@Test
public void processSelfResolutionWhenLeafrefReferToContainerLeaf()
throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/SelfResolutionWhenLeafrefReferToContainerLeaf.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref under module refers to leaf in input of rpc.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToLeafInInputOfRpc()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInModuleReferToLeafInInputOfRpc.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref under module refers to grouping rpc with input as name.
* Rpc has input child also. So here the node search must be done by taking input node.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToGroupingWithInputInRpc()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInModuleReferToGroupingWithInputInRpc.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref under module refers to grouping under module.
* Grouping/typedef cannot be referred.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToGrouping()
throws IOException, ParserException {
thrown.expect(LinkerException.class);
thrown.expectMessage(
"YANG file error: The target node of leafref is invalid.");
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInModuleReferToGroupingInModule.yang");
}
/**
* Checks self resolution error scenerio where leafref is without path.
*/
@Test
public void processSelfResolutionWhenLeafrefDoesntHavePath()
throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage(
"YANG file error : a type leafref must have one path statement.");
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefDoesntHavePath.yang");
}
/**
* Checks self resolution when leafref under module refers to invalid node.
* Inter file linking also has to be done to know the error message.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToInvalidNode()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInModuleReferToInvalidNode.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got intra file resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.INTRA_FILE_RESOLVED));
}
/**
* Checks self resolution when leafref under module refers to invalid node.
* Inter file linking also has to be done to know the error message.
*/
@Test
public void processSelfResolutionWhenLeafrefIsInDeepTreeAndLeafIsInModuleWithReferredTypeUnion()
throws IOException, ParserException {
YangNode node = manager.getDataModel(
"src/test/resources/SelfResolutionWhenLeafrefIsInDeepTreeAndLeafIsInModuleWithReferredTypeUnion.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer containerParent = (YangContainer) yangNode.getChild().getChild().getChild();
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = containerParent.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafInfo.getName(), is("name"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UNION));
}
/**
* Checks self resolution when leafref of leaf-list under module refers to leaf in container.
*/
@Test
public void processSelfResolutionWhenLeafrefReferToContainerLeafList()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefReferToContainerLeafList.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeafList> leafListIterator;
YangLeafList leafListInfo;
leafListIterator = yangNode.getListOfLeafList().listIterator();
leafListInfo = leafListIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafListInfo.getName(), is("network-ref"));
assertThat(leafListInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafListInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafListInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref of leaf-list under module refers to leaf-list in input of rpc.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToLeafListInInputOfRpc()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInModuleReferToLeafListInInputOfRpc.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeafList> leafListIterator;
YangLeafList leafListInfo;
leafListIterator = yangNode.getListOfLeafList().listIterator();
leafListInfo = leafListIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafListInfo.getName(), is("network-ref"));
assertThat(leafListInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafListInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafListInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref of leaf-list under module refers to invalid node.
* Inter file linking also has to be done to know the error message.
*/
@Test
public void processSelfResolutionWhenLeafrefIsInDeepTreeAndLeafListIsInModuleWithReferredTypeEnumeration()
throws IOException, ParserException {
YangNode node = manager.getDataModel(
"src/test/resources/" +
"SelfResolutionWhenLeafrefIsInDeepTreeAndLeafListIsInModuleWithReferredTypeEnumeration.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer containerParent = (YangContainer) yangNode.getChild().getChild().getChild();
ListIterator<YangLeafList> leafListListIterator;
YangLeafList leafListInfo;
leafListListIterator = containerParent.getListOfLeafList().listIterator();
leafListInfo = leafListListIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafListInfo.getName(), is("name"));
assertThat(leafListInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafListInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafListInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.ENUMERATION));
}
/**
* Checks the error scenerio when the referred node is not a leaf or leaf-list.
*/
@Test
public void processSelfResolutionWhenLeafrefDoesNotReferToLeafOrLeafList()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefDoesNotReferToLeafOrLeafList.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
//YangGrouping grouping = (YangGrouping) yangNode.getChild().getNextSibling();
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.INTRA_FILE_RESOLVED));
}
/**
* Checks self resolution when leafref of leaf-list under module refers to leaf in container.
*/
@Test
public void processSelfResolutionWhenLeafrefInTypedefReferToContainer()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInTypedefReferToContainer.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
YangContainer yangContainer = (YangContainer) yangNode.getChild();
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = yangContainer.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("network-id"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref of leaf-list under module refers to leaf-list in input of rpc.
*/
@Test
public void processSelfResolutionWhenLeafrefInTypedefModuleReferToLeafListInInputOfRpc()
throws IOException, ParserException {
YangNode node = manager.getDataModel(
"src/test/resources/SelfResolutionWhenLeafrefInTypedefModuleReferToLeafListInInputOfRpc.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
YangInput yangInput = (YangInput) yangNode.getChild().getChild();
ListIterator<YangLeafList> leafListIterator;
YangLeafList yangLeafListInfo;
leafListIterator = yangInput.getListOfLeafList().listIterator();
yangLeafListInfo = leafListIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(yangLeafListInfo.getName(), is("network-id"));
assertThat(yangLeafListInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (yangLeafListInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref of leaf-list under module refers to invalid node.
* Inter file linking also has to be done to know the error message.
*/
@Test
public void processSelfResolutionWhenLeafrefInTypedefIsInDeepTreeAndLeafListIsInModuleWithReferredTypeEnumeration()
throws IOException, ParserException {
YangNode node = manager.getDataModel(
"src/test/resources/" +
"SelfResolutionWhenLeafrefInTypedefIs" +
"InDeepTreeAndLeafListIsInModuleWithReferredTypeEnumeration.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer yangContainer = (YangContainer) yangNode.getChild().getChild().getChild().getNextSibling();
ListIterator<YangLeaf> leafIterator;
YangLeaf yangLeafInfo;
leafIterator = yangContainer.getListOfLeaf().listIterator();
yangLeafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(yangLeafInfo.getName(), is("interval"));
assertThat(yangLeafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (yangLeafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.ENUMERATION));
}
/**
* Checks self resolution when grouping and uses are siblings.
* Grouping followed by uses.
*/
@Test
public void processSelfResolutionWhenLeafrefRefersAnotherLeafref()
throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/SelfResolutionWhenLeafrefReferToAnotherLeafref.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
//YangGrouping grouping = (YangGrouping) yangNode.getChild().getNextSibling();
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref refers to many other leafref.
*/
@Test
public void processSelfResolutionWhenLeafrefReferToMultipleLeafref()
throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/SelfResolutionWhenLeafrefReferToMultipleLeafref.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer containerInModule = (YangContainer) yangNode.getChild().getNextSibling();
YangContainer containerInList = (YangContainer) containerInModule.getChild().getChild();
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = containerInList.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("remove"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.ENUMERATION));
}
/**
* Checks self resolution when grouping and uses are siblings.
* Grouping followed by uses.
*/
@Test
public void processSelfResolutionWhenLeafrefRefersAnotherDerivedType()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefReferToAnotherDerivedType.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
//YangGrouping grouping = (YangGrouping) yangNode.getChild().getNextSibling();
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.DERIVED));
}
/**
* Checks self resolution when leafref refers to many other leafref.
*/
@Test
public void processSelfResolutionWhenLeafrefReferToMultipleTypedef()
throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/SelfResolutionWhenLeafrefReferToMultipleTypedef.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer containerInModule = (YangContainer) yangNode.getChild().getNextSibling();
YangContainer containerInList = (YangContainer) containerInModule.getChild().getChild();
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = containerInList.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("remove"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.DERIVED));
}
/**
* Checks self resolution when leafref refers to many other leaf with derived type
* which in turn referring to another leaf.
*/
@Test
public void processSelfResolutionWhenLeafrefReferToDerivedTypeReferringToLeafWithLeafref()
throws IOException, ParserException {
YangNode node = manager.getDataModel(
"src/test/resources/SelfResolutionWhenLeafrefReferToDerivedTypeReferringToLeafWithLeafref.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer containerInModule = (YangContainer) yangNode.getChild().getNextSibling();
YangContainer containerInList = (YangContainer) containerInModule.getChild().getChild();
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = containerInList.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("remove"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) leafInfo.getDataType().getDataTypeExtendedInfo();
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.ENUMERATION));
}
/**
* Checks self resolution when leafref under module refers to leaf in container with relative path.
*/
@Test
public void processSelfResolutionWhenLeafrefReferToContainerLeafRelPath()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefReferToContainerLeafRelPath.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref under module refers to grouping rpc with input as name.
* Rpc has input child also. So here the node search must be done by taking input node using relative path.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToGroupingWithInputInRpcRelPath()
throws IOException, ParserException {
YangNode node = manager.getDataModel(
"src/test/resources/SelfResolutionWhenLeafrefInModuleReferToGroupingWithInputInRpcRelPath.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref under module refers to invalid root node with relative path.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToInvalidRootNodeRelPath()
throws IOException, ParserException {
thrown.expect(LinkerException.class);
thrown.expectMessage(
"YANG file error: The target node of leafref is invalid.");
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInModuleReferToInvalidRootNodeRelPath.yang");
}
/**
* Checks self resolution when leafref under module refers to invalid node.
* Inter file linking also has to be done to know the error message with relative path.
*/
@Test
public void processSelfResolutionWhenLeafrefInModuleReferToInvalidNodeRelPath()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInModuleReferToInvalidNodeRelPath.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = yangNode.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct.
assertThat(leafInfo.getName(), is("network-ref"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got intra file resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.INTRA_FILE_RESOLVED));
}
/**
* Checks self resolution when leafref of leaf-list under module refers to leaf in container with relative path.
*/
@Test
public void processSelfResolutionWhenLeafrefInTypedefReferToContainerRelPath()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefInTypedefReferToContainerRelPath.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("ietf-network"));
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
YangContainer yangContainer = (YangContainer) yangNode.getChild();
leafIterator = yangContainer.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("network-id"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
// Check whether leafref type got resolved.
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
// Check the effective type for the leaf.
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.UINT8));
}
/**
* Checks self resolution when leafref refers to many other leafref with relative path.
*/
@Test
public void processSelfResolutionWhenLeafrefReferToMultipleLeafrefRelPath()
throws IOException, ParserException {
YangNode node = manager
.getDataModel("src/test/resources/SelfResolutionWhenLeafrefReferToMultipleLeafrefRelPath.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer containerInModule = (YangContainer) yangNode.getChild().getNextSibling();
YangContainer containerInList = (YangContainer) containerInModule.getChild().getChild();
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = containerInList.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("remove"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) (leafInfo.getDataType().getDataTypeExtendedInfo());
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.ENUMERATION));
}
/**
* Checks self resolution when leafref refers to many other leaf with derived type
* which in turn referring to another leaf with relative type.
*/
@Test
public void processSelfResolutionWhenLeafrefReferToDerivedTypeReferringToLeafWithLeafrefRelType()
throws IOException, ParserException {
YangNode node = manager.getDataModel(
"src/test/resources/SelfResolutionWhenLeafrefReferToDerivedTypeReferringToLeafWithLeafrefRelType.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer containerInModule = (YangContainer) yangNode.getChild().getNextSibling();
YangContainer containerInList = (YangContainer) containerInModule.getChild().getChild();
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
leafIterator = containerInList.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("remove"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) leafInfo.getDataType().getDataTypeExtendedInfo();
assertThat(leafref.getResolvableStatus(),
is(ResolvableStatus.RESOLVED));
assertThat(leafref.getEffectiveDataType().getDataType(),
is(YangDataTypes.ENUMERATION));
}
/**
* Checks the valid scenerios of path argument having proper setters.
*/
@Test
public void processPathArgumentStatement()
throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/PathListener.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("PathListener"));
YangList listInModule = (YangList) yangNode.getChild();
YangContainer containerInModule = (YangContainer) yangNode.getChild().getNextSibling();
ListIterator<YangLeaf> leafIterator;
YangLeaf leafInfo;
YangLeaf leafNameInList = listInModule.getListOfLeaf().listIterator().next();
leafIterator = containerInModule.getListOfLeaf().listIterator();
leafInfo = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo.getName(), is("ifname"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref = (YangLeafRef) leafInfo.getDataType().getDataTypeExtendedInfo();
assertThat(leafref.getPathType(), is(YangPathArgType.RELATIVE_PATH));
YangRelativePath relativePathForName = leafref.getRelativePath();
assertThat(relativePathForName.getAncestorNodeCount(), is(2));
List<YangAtomicPath> absPathForName = relativePathForName.getAtomicPathList();
Iterator<YangAtomicPath> absPathIteratorForName = absPathForName.listIterator();
YangAtomicPath abspathForName = absPathIteratorForName.next();
assertThat(abspathForName.getNodeIdentifier().getName(), is("interface"));
assertThat(abspathForName.getNodeIdentifier().getPrefix(), is("test"));
YangAtomicPath abspath1 = absPathIteratorForName.next();
assertThat(abspath1.getNodeIdentifier().getName(), is("name"));
assertThat(abspath1.getNodeIdentifier().getPrefix(), is("test"));
YangLeaf leafInfo1 = leafIterator.next();
// Check whether the information in the leaf is correct under grouping.
assertThat(leafInfo1.getName(), is("status"));
assertThat(leafInfo1.getDataType().getDataTypeName(), is("leafref"));
assertThat(leafInfo1.getDataType().getDataType(), is(YangDataTypes.LEAFREF));
YangLeafRef leafref1 = (YangLeafRef) leafInfo1.getDataType().getDataTypeExtendedInfo();
assertThat(leafref1.getPathType(), is(YangPathArgType.ABSOLUTE_PATH));
List<YangAtomicPath> absolutePathList = leafref1.getAtomicPath();
Iterator<YangAtomicPath> absPathIterator = absolutePathList.listIterator();
YangAtomicPath abspath = absPathIterator.next();
assertThat(abspath.getNodeIdentifier().getName(), is("interface"));
assertThat(abspath.getNodeIdentifier().getPrefix(), is("test"));
List<YangPathPredicate> pathPredicateList = abspath.getPathPredicatesList();
Iterator<YangPathPredicate> pathPredicate = pathPredicateList.listIterator();
YangPathPredicate pathPredicate1 = pathPredicate.next();
assertThat(pathPredicate1.getNodeIdentifier().getName(), is("name"));
assertThat(pathPredicate1.getNodeIdentifier().getPrefix(), nullValue());
assertThat(pathPredicate1.getRightRelativePath().getAncestorNodeCount(), is(1));
assertThat(pathPredicate1.getPathOperator(), is(YangPathOperator.EQUALTO));
assertThat(pathPredicate1.getRightRelativePath().getAtomicPathList().listIterator().next().getNodeIdentifier()
.getName(), is("ifname"));
YangAtomicPath abspath2 = absPathIterator.next();
assertThat(abspath2.getNodeIdentifier().getName(), is("admin-status"));
assertThat(abspath2.getNodeIdentifier().getPrefix(), is("test"));
assertThat(pathPredicate1.getLeftAxisNode(), is(leafNameInList));
assertThat(pathPredicate1.getRightAxisNode(), is(leafInfo));
}
}
module PathListener {
namespace "test";
prefix test;
list interface {
key "name";
leaf name {
type string;
}
leaf admin-status {
type string;
}
list address {
key "ip";
leaf ip {
type string;
}
}
}
container default-address {
leaf ifname {
type leafref {
path "../../test:interface/test:name";
}
}
leaf status {
type leafref {
path "/test:interface[name = current()/../ifname]/test:admin-status";
}
}
}
}
\ No newline at end of file
module PathListener {
namespace "test";
prefix test;
list interface {
key "name";
leaf name {
type string;
}
leaf admin-status {
type string;
}
list address {
key "ip";
leaf ip {
type string;
}
}
}
container default-address {
leaf ifname {
type leafref {
path "../../test:interface/test:name";
}
}
leaf status {
type leafref {
path "/test:interface[name = current()/../ifname]/test:admin-status";
}
}
}
}
\ No newline at end of file
module PathListener {
namespace "test";
prefix test;
leaf admin-status {
type instance-identifier;
}
}
\ No newline at end of file
module PathListener {
namespace "test";
prefix test;
leaf admin-status {
type instance-identifier {
require-instance "false";
}
}
}
\ No newline at end of file
module PathListener {
namespace "test";
prefix test;
list interface {
key "name";
leaf name {
type string;
}
leaf admin-status {
type string;
}
list address {
key "ip";
leaf ip {
type string;
}
}
}
container default-address {
leaf ifname {
type leafref {
path "../../test:interface/test:name";
require-instance true;
}
}
leaf status {
type leafref {
path "/test:interface[name = current()/../ifname]/test:admin-status";
}
}
}
}
\ No newline at end of file
module syslog {
yang-version 1;
namespace http://huawei.com;
prefix "sys";
feature local-storage {
description
"This feature means the device supports local
storage (memory, flash or disk) that can be used to
store syslog messages.";
}
container speed {
leaf local-storage-limit {
if-feature local-storage;
type uint64;
units "kilobyte";
config false;
description
"The amount of local storage that can be
used to hold syslog messages.";
}
}
leaf storage-value {
type leafref {
path "/speed/local-storage-limit";
}
}
}
module syslog {
yang-version 1;
namespace http://huawei.com;
prefix "sys";
feature local-storage {
description
"This feature means the device supports local
storage (memory, flash or disk) that can be used to
store syslog messages.";
}
feature main-storage {
description
"This feature means the device supports main
storage that can be used to
store syslog messages.";
}
container speed {
leaf local-storage-limit {
if-feature local-storage;
type leafref {
path "/value";
}
units "kilobyte";
config false;
description
"The amount of local storage that can be
used to hold syslog messages.";
}
}
leaf storage-value {
type leafref {
path "/speed/local-storage-limit";
}
}
leaf value {
if-feature main-storage;
type uint64;
}
}
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type status;
description
"Identifies a network.";
}
}
typedef status {
type uint8;
}
leaf network-ref {
type leafref {
path "/networks";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf-list network-ref {
type leafref;
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
rpc networks {
description
"Serves as top-level container for a list of networks.";
grouping input {
leaf network-id {
type string;
description
"Identifies a network.";
}
}
input {
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
output {
}
}
leaf network-ref {
type leafref {
path "/networks/input/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
grouping networks {
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
container current {
leaf network-ref {
type leafref {
path "/networks/network-id";
}
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
rpc networks {
description
"Serves as top-level container for a list of networks.";
grouping input {
leaf network-id {
type string;
description
"Identifies a network.";
}
}
input {
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
}
leaf network-ref {
type leafref {
path "/networks/input/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
rpc networks {
description
"Serves as top-level container for a list of networks.";
grouping input {
leaf network-id {
type string;
description
"Identifies a network.";
}
}
input {
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
}
leaf network-ref {
type leafref {
path "../networks/input/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf network-ref {
type leafref {
path "/define/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf network-ref {
type leafref {
path "../define/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf network-ref {
type leafref {
path "../../../define/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
rpc networks {
description
"Serves as top-level container for a list of networks.";
input {
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
output {
}
}
leaf network-ref {
type leafref {
path "/networks/input/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
rpc networks {
description
"Serves as top-level container for a list of networks.";
input {
leaf-list network-id {
type uint8;
description
"Identifies a network.";
}
}
output {
}
}
leaf-list network-ref {
type leafref {
path "/networks/input/network-id";
}
}
}
\ No newline at end of file
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "define";
leaf define {
type string;
}
container standard {
typedef node {
type leafref {
path "/invalid-interval";
}
}
container present {
typedef name {
type node;
}
leaf interval {
type name;
}
}
}
}
leaf-list invalid-interval {
type enumeration {
enum 10m;
enum 100m;
enum auto;
}
}
}
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
rpc networks {
description
"Serves as top-level container for a list of networks.";
input {
leaf-list network-id {
type network-ref;
description
"Identifies a network.";
}
leaf id {
type uint8;
}
}
output {
}
}
typedef network-ref {
type leafref {
path "/networks/input/id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type network-ref;
description
"Identifies a network.";
}
leaf id {
type uint8;
}
}
typedef network-ref {
type leafref {
path "/networks/id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type network-ref;
description
"Identifies a network.";
}
leaf id {
type uint8;
}
}
typedef network-ref {
type leafref {
path "../id";
}
}
}
\ No newline at end of file
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "define";
leaf define {
type string;
}
container standard {
container present {
leaf name {
type leafref {
path "/invalid-interval";
}
}
}
}
}
leaf invalid-interval {
type union {
type int32;
type enumeration {
enum "unbounded";
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "define";
leaf define {
type string;
}
container standard {
container present {
leaf-list name {
type leafref {
path "/invalid-interval";
}
}
}
}
}
leaf-list invalid-interval {
type enumeration {
enum 10m;
enum 100m;
enum auto;
}
}
}
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type status;
description
"Identifies a network.";
}
}
typedef status {
type uint8;
}
leaf network-ref {
type leafref {
path "/networks/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type leafref {
path "/status/current";
}
description
"Identifies a network.";
}
}
container status {
leaf current {
type uint8;
}
}
leaf network-ref {
type leafref {
path "/networks/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf network-ref {
type leafref {
path "/networks/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf-list network-ref {
type leafref {
path "/networks/network-id";
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf network-ref {
type leafref {
path "../networks/network-id";
}
}
}
\ No newline at end of file
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "define";
leaf define {
type string;
}
container standard {
container present {
leaf-list name {
type transmitter;
}
}
}
}
container reference {
list found {
key "define";
leaf define {
type string;
}
container reciever {
leaf remove {
type leafref {
path "/valid/standard/present/name";
}
}
}
}
}
typedef transmitter {
type leafref {
path "/invalid-interval";
}
}
leaf invalid-interval {
type enumeration {
enum 10m;
enum 100m;
enum auto;
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "define";
leaf define {
type string;
}
container standard {
container present {
leaf-list name {
type transmitter;
}
}
}
}
container reference {
list found {
key "define";
leaf define {
type string;
}
container reciever {
leaf remove {
type leafref {
path "../../../../valid/standard/present/name";
}
}
}
}
}
typedef transmitter {
type leafref {
path "../../../../invalid-interval";
}
}
leaf invalid-interval {
type enumeration {
enum 10m;
enum 100m;
enum auto;
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "define";
leaf define {
type string;
}
container standard {
container present {
leaf-list name {
type leafref {
path "/transmitter/send";
}
}
}
}
}
container reference {
list found {
key "define";
leaf define {
type string;
}
container reciever {
leaf remove {
type leafref {
path "/valid/standard/present/name";
}
}
}
}
}
list transmitter {
key "send";
leaf send {
type leafref {
path "/invalid-interval";
}
}
}
leaf-list invalid-interval {
type enumeration {
enum 10m;
enum 100m;
enum auto;
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "define";
leaf define {
type string;
}
container standard {
container present {
leaf-list name {
type leafref {
path "../../../../transmitter/send";
}
}
}
}
}
container reference {
list found {
key "define";
leaf define {
type string;
}
container reciever {
leaf remove {
type leafref {
path "../../../../valid/standard/present/name";
}
}
}
}
}
list transmitter {
key "send";
leaf send {
type leafref {
path "../../invalid-interval";
}
}
}
leaf-list invalid-interval {
type enumeration {
enum 10m;
enum 100m;
enum auto;
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "define";
leaf define {
type string;
}
container standard {
container present {
leaf-list name {
type transmitter;
}
}
}
}
container reference {
list found {
key "define";
leaf define {
type string;
}
container reciever {
leaf remove {
type leafref {
path "/valid/standard/present/name";
}
}
}
}
}
typedef transmitter {
type invalid-interval;
}
typedef invalid-interval {
type enumeration {
enum 10m;
enum 100m;
enum auto;
}
}
}
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type uint8;
description
"Identifies a network.";
}
}
leaf network-ref {
type leafref {
path "/define/network-id";
}
}
}
\ No newline at end of file
module module1 {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
import module2 {
prefix p;
}
leaf invalid-interval {
type leafref {
path "/p:hello";
}
}
leaf hello {
type string;
}
}
\ No newline at end of file
module Test {
module module2 {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf-list invalid-interval {
type leafref;
prefix Ant2;
leaf hello {
type string;
}
}
......
module module1 {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-te-topology";
prefix "tet";
import module2 {
prefix "nt";
}
grouping te-node-tunnel-termination-capability {
description
"Termination capability of a tunnel termination point on a
TE node.";
list termination-capability {
key "link-tp";
description
"The termination capabilities between
tunnel-termination-point and link termination-point.
The capability information can be used to compute
the tunnel path.";
leaf link-tp {
type leafref {
path "/nt:termination-point/nt:tp-id";
}
description
"Link termination point.";
}
} // termination-capability
} // te-node-tunnel-termination-capability
}
\ No newline at end of file
module module2 {
yang-version 1;
namespace
"urn:ietf:params:xml:ns:yang:ietf-inet-types";
prefix inet;
container termination-point {
leaf tp-id {
type string;
}
}
}
\ No newline at end of file
module ietf-inet-types {
yang-version 1;
namespace
"urn:ietf:params:xml:ns:yang:ietf-inet-types";
prefix inet;
typedef tp-ref {
type leafref {
path "/nwtp:value";
}
}
}
\ No newline at end of file
module ietf-network-topology {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-te-topology";
prefix "tet";
import ietf-network {
prefix "nt";
}
grouping te-node-tunnel-termination-capability {
description
"Termination capability of a tunnel termination point on a
TE node.";
list termination-capability {
key "link-tp";
description
"The termination capabilities between
tunnel-termination-point and link termination-point.
The capability information can be used to compute
the tunnel path.";
leaf link-tp {
type leafref {
path "/nt:termination-point/nt:tp-id";
}
description
"Link termination point.";
}
} // termination-capability
} // te-node-tunnel-termination-capability
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace
"urn:ietf:params:xml:ns:yang:ietf-inet-types";
prefix nw;
import ietf-inet-types {
prefix inet;
}
container termination-point {
leaf tp-id {
type string;
}
}
}
\ No newline at end of file
module ietf-network {
yang-version 1;
namespace "urn:ietf:params:xml:ns:yang:ietf-network";
prefix nd;
container networks {
description
"Serves as top-level container for a list of networks.";
leaf network-id {
type status;
description
"Identifies a network.";
}
}
typedef status {
type uint8;
}
leaf network-ref {
type leafref {
path "/networks";
}
}
}
\ No newline at end of file