YANG: Restriction resolution implementation
Change-Id: I69503e8229def07b289a0c8c762bfe0ae5530232
diff --git a/src/main/java/org/onosproject/yangutils/utils/RestrictionResolver.java b/src/main/java/org/onosproject/yangutils/utils/RestrictionResolver.java
new file mode 100644
index 0000000..6227126
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/utils/RestrictionResolver.java
@@ -0,0 +1,255 @@
+/*
+ * 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.utils;
+
+import java.util.regex.Pattern;
+import org.onosproject.yangutils.datamodel.YangDataTypes;
+import org.onosproject.yangutils.datamodel.YangRangeInterval;
+import org.onosproject.yangutils.datamodel.YangRangeRestriction;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.utils.builtindatatype.DataTypeException;
+import org.onosproject.yangutils.utils.builtindatatype.YangBuiltInDataTypeInfo;
+
+import static org.onosproject.yangutils.datamodel.YangDataTypes.DECIMAL64;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT16;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT32;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT64;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT8;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT16;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT32;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT64;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT8;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
+import static org.onosproject.yangutils.utils.YangConstructType.LENGTH_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.RANGE_DATA;
+import static org.onosproject.yangutils.utils.builtindatatype.BuiltInTypeObjectFactory.getDataObjectFromString;
+
+/**
+ * Represents restriction resolver which provide common utility used by parser
+ * and during linking for restriction resolution.
+ */
+public final class RestrictionResolver {
+
+ private static final String PIPE = "|";
+ private static final String INTERVAL = "..";
+ private static final int MAX_RANGE_BOUNDARY = 2;
+ private static final int MIN_RANGE_BOUNDARY = 1;
+ private static final String MIN_KEYWORD = "min";
+ private static final String MAX_KEYWORD = "max";
+
+ /**
+ * Creates a restriction resolver.
+ */
+ private RestrictionResolver() {
+ }
+
+ /**
+ * Processes the range restriction for parser and linker.
+ *
+ * @param refRangeRestriction range restriction of referred typedef
+ * @param lineNumber error line number
+ * @param charPositionInLine error character position in line
+ * @param hasReferredRestriction whether has referred restriction
+ * @param curRangeString caller type's range string
+ * @param effectiveType effective type, when called from linker
+ * @return YANG range restriction
+ */
+ public static YangRangeRestriction processRangeRestriction(YangRangeRestriction refRangeRestriction,
+ int lineNumber, int charPositionInLine,
+ boolean hasReferredRestriction,
+ String curRangeString, YangDataTypes effectiveType) {
+ YangBuiltInDataTypeInfo<?> startValue;
+ YangBuiltInDataTypeInfo<?> endValue;
+ YangRangeRestriction rangeRestriction = new YangRangeRestriction();
+
+ String rangeArgument = removeQuotesAndHandleConcat(curRangeString);
+ String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
+
+ for (String rangePart : rangeArguments) {
+ String startInterval;
+ String endInterval;
+ YangRangeInterval rangeInterval = new YangRangeInterval();
+ String[] rangeBoundary = rangePart.trim().split(Pattern.quote(INTERVAL));
+
+ if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
+ ParserException parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(RANGE_DATA) + " " + rangeArgument +
+ " is not valid.");
+ parserException.setLine(lineNumber);
+ parserException.setCharPosition(charPositionInLine);
+ throw parserException;
+ }
+
+ if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
+ startInterval = rangeBoundary[0];
+ endInterval = rangeBoundary[0];
+ } else {
+ startInterval = rangeBoundary[0];
+ endInterval = rangeBoundary[1];
+ }
+
+ try {
+ if (hasReferredRestriction && startInterval.equals(MIN_KEYWORD)
+ && refRangeRestriction.getMinRestrictedvalue() != null) {
+ startValue = refRangeRestriction.getMinRestrictedvalue();
+ } else if (hasReferredRestriction && startInterval.equals(MAX_KEYWORD)
+ && refRangeRestriction.getMaxRestrictedvalue() != null) {
+ startValue = refRangeRestriction.getMaxRestrictedvalue();
+ } else {
+ startValue = getDataObjectFromString(startInterval, effectiveType);
+ }
+ if (hasReferredRestriction && endInterval.equals(MIN_KEYWORD)
+ && refRangeRestriction.getMinRestrictedvalue() != null) {
+ endValue = refRangeRestriction.getMinRestrictedvalue();
+ } else if (hasReferredRestriction && endInterval.equals(MAX_KEYWORD)
+ && refRangeRestriction.getMaxRestrictedvalue() != null) {
+ endValue = refRangeRestriction.getMaxRestrictedvalue();
+ } else {
+ endValue = getDataObjectFromString(endInterval, effectiveType);
+ }
+ } catch (DataTypeException | DataModelException e) {
+ ParserException parserException = new ParserException(e.getMessage());
+ parserException.setLine(lineNumber);
+ parserException.setCharPosition(charPositionInLine);
+ throw parserException;
+ }
+
+ rangeInterval.setStartValue(startValue);
+ rangeInterval.setEndValue(endValue);
+
+ try {
+ rangeRestriction.addRangeRestrictionInterval(rangeInterval);
+ } catch (DataModelException e) {
+ ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
+ UNHANDLED_PARSED_DATA, RANGE_DATA, rangeArgument, ENTRY, e.getMessage()));
+ parserException.setLine(lineNumber);
+ parserException.setCharPosition(charPositionInLine);
+ throw parserException;
+ }
+ }
+ return rangeRestriction;
+ }
+
+ /**
+ * Processes the length restriction for parser and linker.
+ *
+ * @param refLengthRestriction length restriction of referred typedef
+ * @param lineNumber error line number
+ * @param charPositionInLine error character position in line
+ * @param hasReferredRestriction whether has referred restriction
+ * @param curLengthString caller type's length string
+ * @return YANG range restriction
+ */
+ public static YangRangeRestriction processLengthRestriction(YangRangeRestriction refLengthRestriction,
+ int lineNumber, int charPositionInLine,
+ boolean hasReferredRestriction,
+ String curLengthString) {
+
+ YangBuiltInDataTypeInfo<?> startValue;
+ YangBuiltInDataTypeInfo<?> endValue;
+ YangRangeRestriction lengthRestriction = new YangRangeRestriction<>();
+
+ String rangeArgument = removeQuotesAndHandleConcat(curLengthString);
+ String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
+
+ for (String rangePart : rangeArguments) {
+ String startInterval;
+ String endInterval;
+ YangRangeInterval rangeInterval = new YangRangeInterval<>();
+ String[] rangeBoundary = rangePart.trim().split(Pattern.quote(INTERVAL));
+
+ if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
+ ParserException parserException = new ParserException("YANG file error : " +
+ YangConstructType.getYangConstructType(LENGTH_DATA) + " " + rangeArgument +
+ " is not valid.");
+ parserException.setLine(lineNumber);
+ parserException.setCharPosition(charPositionInLine);
+ throw parserException;
+ }
+
+ if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
+ startInterval = rangeBoundary[0];
+ endInterval = rangeBoundary[0];
+ } else {
+ startInterval = rangeBoundary[0];
+ endInterval = rangeBoundary[1];
+ }
+
+ try {
+ if (hasReferredRestriction && startInterval.equals(MIN_KEYWORD)
+ && refLengthRestriction.getMinRestrictedvalue() != null) {
+ startValue = refLengthRestriction.getMinRestrictedvalue();
+ } else if (hasReferredRestriction && startInterval.equals(MAX_KEYWORD)
+ && refLengthRestriction.getMaxRestrictedvalue() != null) {
+ startValue = refLengthRestriction.getMaxRestrictedvalue();
+ } else {
+ startValue = getDataObjectFromString(startInterval, YangDataTypes.UINT64);
+ }
+ if (hasReferredRestriction && endInterval.equals(MIN_KEYWORD)
+ && refLengthRestriction.getMinRestrictedvalue() != null) {
+ endValue = refLengthRestriction.getMinRestrictedvalue();
+ } else if (hasReferredRestriction && endInterval.equals(MAX_KEYWORD)
+ && refLengthRestriction.getMaxRestrictedvalue() != null) {
+ endValue = refLengthRestriction.getMaxRestrictedvalue();
+ } else {
+ endValue = getDataObjectFromString(endInterval, YangDataTypes.UINT64);
+ }
+ } catch (DataTypeException | DataModelException e) {
+ ParserException parserException = new ParserException(e.getMessage());
+ parserException.setLine(lineNumber);
+ parserException.setCharPosition(charPositionInLine);
+ throw parserException;
+ }
+
+ rangeInterval.setStartValue(startValue);
+ rangeInterval.setEndValue(endValue);
+
+ try {
+ lengthRestriction.addRangeRestrictionInterval(rangeInterval);
+ } catch (DataModelException e) {
+ ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
+ UNHANDLED_PARSED_DATA, LENGTH_DATA, rangeArgument, ENTRY, e.getMessage()));
+ parserException.setLine(lineNumber);
+ parserException.setCharPosition(charPositionInLine);
+ throw parserException;
+ }
+ }
+ return lengthRestriction;
+ }
+
+ /**
+ * Returns whether the data type is of range restricted type.
+ *
+ * @param dataType data type to be checked
+ * @return true, if data type can have range restrictions, false otherwise
+ */
+ public static boolean isOfRangeRestrictedType(YangDataTypes dataType) {
+ return (dataType == INT8
+ || dataType == INT16
+ || dataType == INT32
+ || dataType == INT64
+ || dataType == UINT8
+ || dataType == UINT16
+ || dataType == UINT32
+ || dataType == UINT64
+ || dataType == DECIMAL64);
+ }
+}
diff --git a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt16.java b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt16.java
index 1ad76b5..f9055e8 100644
--- a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt16.java
+++ b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt16.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.yangutils.utils.builtindatatype;
import org.onosproject.yangutils.datamodel.YangDataTypes;
@@ -66,7 +67,8 @@
try {
value = Short.parseShort(valueInString);
} catch (Exception e) {
- throw new DataTypeException("YANG file error : " + valueInString + " is not valid.");
+ throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+ "int16.");
}
}
}
diff --git a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt32.java b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt32.java
index 93dcec6..2f48f33 100644
--- a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt32.java
+++ b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt32.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.yangutils.utils.builtindatatype;
import org.onosproject.yangutils.datamodel.YangDataTypes;
@@ -65,7 +66,8 @@
try {
value = Integer.parseInt(valueInString);
} catch (Exception e) {
- throw new DataTypeException("YANG file error : " + valueInString + " is not valid.");
+ throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+ "int32.");
}
}
}
diff --git a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt64.java b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt64.java
index a046ee8..6b0b685 100644
--- a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt64.java
+++ b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt64.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.yangutils.utils.builtindatatype;
import org.onosproject.yangutils.datamodel.YangDataTypes;
@@ -65,7 +66,8 @@
try {
value = Long.parseLong(valueInString);
} catch (Exception e) {
- throw new DataTypeException("YANG file error : " + valueInString + " is not valid.");
+ throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+ "int64.");
}
}
}
diff --git a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt8.java b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt8.java
index c902410..b2823e5 100644
--- a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt8.java
+++ b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangInt8.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.yangutils.utils.builtindatatype;
import org.onosproject.yangutils.datamodel.YangDataTypes;
@@ -65,7 +66,8 @@
try {
value = Byte.parseByte(valueInString);
} catch (Exception e) {
- throw new DataTypeException("YANG file error : " + valueInString + " is not valid.");
+ throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+ "int8.");
}
}
}
diff --git a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint16.java b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint16.java
index b109103..53c3a50 100644
--- a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint16.java
+++ b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint16.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.yangutils.utils.builtindatatype;
import org.onosproject.yangutils.datamodel.YangDataTypes;
@@ -65,7 +66,8 @@
try {
value = Integer.parseInt(valueInString);
} catch (Exception e) {
- throw new DataTypeException("YANG file error : " + valueInString + " is not valid.");
+ throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+ "uint16.");
}
}
diff --git a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint32.java b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint32.java
index e356055..79d1c6d 100644
--- a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint32.java
+++ b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint32.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.yangutils.utils.builtindatatype;
import org.onosproject.yangutils.datamodel.YangDataTypes;
@@ -58,7 +59,8 @@
try {
value = Long.parseLong(valueInString);
} catch (Exception e) {
- throw new DataTypeException("YANG file error : " + valueInString + " is not valid.");
+ throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+ "uint32.");
}
}
diff --git a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint64.java b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint64.java
index 70001ae..cc16a7a 100644
--- a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint64.java
+++ b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint64.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.yangutils.utils.builtindatatype;
import java.math.BigInteger;
@@ -71,7 +72,8 @@
} else if (NON_NEGATIVE_INTEGER_PATTERN.matcher(valueInString).matches()) {
value = new BigInteger(valueInString);
} else {
- throw new DataTypeException("YANG file error : " + valueInString + " is not valid.");
+ throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+ "uint64.");
}
if (value.compareTo(MIN_VALUE) < 0) {
diff --git a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint8.java b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint8.java
index caf0628..b9abf4c 100644
--- a/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint8.java
+++ b/src/main/java/org/onosproject/yangutils/utils/builtindatatype/YangUint8.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.yangutils.utils.builtindatatype;
import org.onosproject.yangutils.datamodel.YangDataTypes;
@@ -65,7 +66,8 @@
try {
value = Short.parseShort(valueInString);
} catch (Exception e) {
- throw new DataTypeException("YANG file error : " + valueInString + " is not valid.");
+ throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+ "uint8.");
}
}