*/
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.length;
+import com.google.common.collect.Iterables;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnresolvedNumber;
import org.opendaylight.yangtools.yang.model.api.stmt.ValueRange;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
public final class LengthStatementSupport extends AbstractStatementSupport<List<ValueRange>, LengthStatement,
@Override
public List<ValueRange> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
- return TypeUtils.parseLengthListFromString(ctx, value);
+ final List<ValueRange> ranges = new ArrayList<>();
+
+ for (final String singleRange : TypeUtils.PIPE_SPLITTER.split(value)) {
+ final Iterator<String> boundaries = TypeUtils.TWO_DOTS_SPLITTER.split(singleRange).iterator();
+ final Number min = parseIntegerConstraintValue(ctx, boundaries.next());
+
+ final Number max;
+ if (boundaries.hasNext()) {
+ max = parseIntegerConstraintValue(ctx, boundaries.next());
+
+ // if min larger than max then error
+ SourceException.throwIf(TypeUtils.compareNumbers(min, max) == 1, ctx.getStatementSourceReference(),
+ "Length constraint %s has descending order of boundaries; should be ascending.", singleRange);
+ SourceException.throwIf(boundaries.hasNext(), ctx.getStatementSourceReference(),
+ "Wrong number of boundaries in length constraint %s.", singleRange);
+ } else {
+ max = min;
+ }
+
+ // some of intervals overlapping
+ InferenceException.throwIf(ranges.size() > 1
+ && TypeUtils.compareNumbers(min, Iterables.getLast(ranges).upperBound()) != 1,
+ ctx.getStatementSourceReference(), "Some of the length ranges in %s are not disjoint",
+ value);
+ ranges.add(ValueRange.of(min, max));
+ }
+
+ return ranges;
}
@Override
protected SubstatementValidator getSubstatementValidator() {
return SUBSTATEMENT_VALIDATOR;
}
+
+ private static Number parseIntegerConstraintValue(final StmtContext<?, ?, ?> ctx, final String value) {
+ if ("max".equals(value)) {
+ return UnresolvedNumber.max();
+ }
+ if ("min".equals(value)) {
+ return UnresolvedNumber.min();
+ }
+
+ try {
+ return new BigInteger(value);
+ } catch (final NumberFormatException e) {
+ throw new SourceException(ctx.getStatementSourceReference(), e, "Value %s is not a valid integer", value);
+ }
+ }
}
\ No newline at end of file
*/
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.range;
+import com.google.common.collect.Iterables;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnresolvedNumber;
import org.opendaylight.yangtools.yang.model.api.stmt.ValueRange;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
public final class RangeStatementSupport extends AbstractStatementSupport<List<ValueRange>, RangeStatement,
}
@Override
- public List<ValueRange> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
- return TypeUtils.parseRangeListFromString(ctx, value);
+ public List<ValueRange> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String rangeArgument) {
+ final List<ValueRange> ranges = new ArrayList<>();
+
+ for (final String singleRange : TypeUtils.PIPE_SPLITTER.split(rangeArgument)) {
+ final Iterator<String> boundaries = TypeUtils.TWO_DOTS_SPLITTER.split(singleRange).iterator();
+ final Number min = parseDecimalConstraintValue(ctx, boundaries.next());
+
+ final Number max;
+ if (boundaries.hasNext()) {
+ max = parseDecimalConstraintValue(ctx, boundaries.next());
+
+ // if min larger than max then error
+ SourceException.throwIf(TypeUtils.compareNumbers(min, max) == 1, ctx.getStatementSourceReference(),
+ "Range constraint %s has descending order of boundaries; should be ascending", singleRange);
+ SourceException.throwIf(boundaries.hasNext(), ctx.getStatementSourceReference(),
+ "Wrong number of boundaries in range constraint %s", singleRange);
+ } else {
+ max = min;
+ }
+
+ // some of intervals overlapping
+ InferenceException.throwIf(ranges.size() > 1
+ && TypeUtils.compareNumbers(min, Iterables.getLast(ranges).upperBound()) != 1,
+ ctx.getStatementSourceReference(), "Some of the value ranges in %s are not disjoint",
+ rangeArgument);
+ ranges.add(ValueRange.of(min, max));
+ }
+
+ return ranges;
}
@Override
protected SubstatementValidator getSubstatementValidator() {
return SUBSTATEMENT_VALIDATOR;
}
+
+ private static Number parseDecimalConstraintValue(final StmtContext<?, ?, ?> ctx, final String value) {
+ if ("max".equals(value)) {
+ return UnresolvedNumber.max();
+ }
+ if ("min".equals(value)) {
+ return UnresolvedNumber.min();
+ }
+
+ try {
+ return value.indexOf('.') != -1 ? new BigDecimal(value) : new BigInteger(value);
+ } catch (final NumberFormatException e) {
+ throw new SourceException(String.format("Value %s is not a valid decimal number", value),
+ ctx.getStatementSourceReference(), e);
+ }
+ }
}
\ No newline at end of file
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
-import com.google.common.collect.Iterables;
import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.List;
import java.util.Set;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.YangVersion;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.UnresolvedNumber;
-import org.opendaylight.yangtools.yang.model.api.stmt.ValueRange;
import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
/**
-* Utility class for manipulating YANG base and extended types implementation.
-*/
+ * Utility class for manipulating YANG base and extended types implementation.
+ */
public final class TypeUtils {
-
- private static final Splitter PIPE_SPLITTER = Splitter.on('|').trimResults();
- private static final Splitter TWO_DOTS_SPLITTER = Splitter.on("..").trimResults();
+ public static final Splitter PIPE_SPLITTER = Splitter.on('|').trimResults();
+ public static final Splitter TWO_DOTS_SPLITTER = Splitter.on("..").trimResults();
// these objects are to compare whether range has MAX or MIN value
// none of these values should appear as Yang number according to spec so they are safe to use
return new BigDecimal(number.toString());
}
- private static int compareNumbers(final Number n1, final Number n2) {
-
+ public static int compareNumbers(final Number n1, final Number n2) {
final BigDecimal num1 = yangConstraintToBigDecimal(n1);
final BigDecimal num2 = yangConstraintToBigDecimal(n2);
-
return new BigDecimal(num1.toString()).compareTo(new BigDecimal(num2.toString()));
}
- private static Number parseIntegerConstraintValue(final StmtContext<?, ?, ?> ctx, final String value) {
- if ("max".equals(value)) {
- return UnresolvedNumber.max();
- }
- if ("min".equals(value)) {
- return UnresolvedNumber.min();
- }
-
- try {
- return new BigInteger(value);
- } catch (final NumberFormatException e) {
- throw new SourceException(ctx.getStatementSourceReference(), e, "Value %s is not a valid integer", value);
- }
- }
-
- private static Number parseDecimalConstraintValue(final StmtContext<?, ?, ?> ctx, final String value) {
- if ("max".equals(value)) {
- return UnresolvedNumber.max();
- }
- if ("min".equals(value)) {
- return UnresolvedNumber.min();
- }
-
- try {
- return value.indexOf('.') != -1 ? new BigDecimal(value) : new BigInteger(value);
- } catch (final NumberFormatException e) {
- throw new SourceException(String.format("Value %s is not a valid decimal number", value),
- ctx.getStatementSourceReference(), e);
- }
- }
-
- public static List<ValueRange> parseRangeListFromString(final StmtContext<?, ?, ?> ctx,
- final String rangeArgument) {
- final List<ValueRange> ranges = new ArrayList<>();
-
- for (final String singleRange : PIPE_SPLITTER.split(rangeArgument)) {
- final Iterator<String> boundaries = TWO_DOTS_SPLITTER.split(singleRange).iterator();
- final Number min = parseDecimalConstraintValue(ctx, boundaries.next());
-
- final Number max;
- if (boundaries.hasNext()) {
- max = parseDecimalConstraintValue(ctx, boundaries.next());
-
- // if min larger than max then error
- SourceException.throwIf(compareNumbers(min, max) == 1, ctx.getStatementSourceReference(),
- "Range constraint %s has descending order of boundaries; should be ascending", singleRange);
- SourceException.throwIf(boundaries.hasNext(), ctx.getStatementSourceReference(),
- "Wrong number of boundaries in range constraint %s", singleRange);
- } else {
- max = min;
- }
-
- // some of intervals overlapping
- InferenceException.throwIf(ranges.size() > 1
- && compareNumbers(min, Iterables.getLast(ranges).upperBound()) != 1,
- ctx.getStatementSourceReference(), "Some of the value ranges in %s are not disjoint",
- rangeArgument);
- ranges.add(ValueRange.of(min, max));
- }
-
- return ranges;
- }
-
- public static List<ValueRange> parseLengthListFromString(final StmtContext<?, ?, ?> ctx,
- final String lengthArgument) {
- final List<ValueRange> ranges = new ArrayList<>();
-
- for (final String singleRange : PIPE_SPLITTER.split(lengthArgument)) {
- final Iterator<String> boundaries = TWO_DOTS_SPLITTER.split(singleRange).iterator();
- final Number min = parseIntegerConstraintValue(ctx, boundaries.next());
-
- final Number max;
- if (boundaries.hasNext()) {
- max = parseIntegerConstraintValue(ctx, boundaries.next());
-
- // if min larger than max then error
- SourceException.throwIf(compareNumbers(min, max) == 1, ctx.getStatementSourceReference(),
- "Length constraint %s has descending order of boundaries; should be ascending.", singleRange);
- SourceException.throwIf(boundaries.hasNext(), ctx.getStatementSourceReference(),
- "Wrong number of boundaries in length constraint %s.", singleRange);
- } else {
- max = min;
- }
-
- // some of intervals overlapping
- InferenceException.throwIf(ranges.size() > 1
- && compareNumbers(min, Iterables.getLast(ranges).upperBound()) != 1,
- ctx.getStatementSourceReference(), "Some of the length ranges in %s are not disjoint",
- lengthArgument);
- ranges.add(ValueRange.of(min, max));
- }
-
- return ranges;
- }
-
/**
* Checks whether supplied type has any of specified default values marked
* with an if-feature. This method creates mutable copy of supplied set of