Bug 3670 (part 1/5): Use of new statement parser in yang-maven-plugin
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / effective / type / Decimal64SpecificationEffectiveStatementImpl.java
index 73d6d34ad09686cad14f4d0b29c12e46c717c8ca..6dddaafa30b9fe70a897e255123ca0670ac95bf0 100644 (file)
@@ -7,8 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type;
 
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType.Builder;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase;
-
 import org.opendaylight.yangtools.yang.model.util.Decimal64;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
 import com.google.common.base.Optional;
@@ -31,11 +33,13 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.FractionDigitsEffectiveStatementImpl;
 
 public class Decimal64SpecificationEffectiveStatementImpl extends
-        EffectiveStatementBase<String, TypeStatement.Decimal64Specification> implements DecimalTypeDefinition, TypeDefinitionEffectiveBuilder {
+        EffectiveStatementBase<String, TypeStatement.Decimal64Specification>
+        implements DecimalTypeDefinition, TypeDefinitionEffectiveBuilder {
 
     private static final String UNITS = "";
     private static final BigDecimal DEFAULT_VALUE = null;
-    private static final QName QNAME = QName.create(YangConstants.RFC6020_YANG_MODULE, TypeUtils.DECIMAL64);
+    private static final QName QNAME = QName.create(
+            YangConstants.RFC6020_YANG_MODULE, TypeUtils.DECIMAL64);
 
     private static final String DESCRIPTION = "The decimal64 type represents a subset of the real numbers, which can "
             + "be represented by decimal numerals. The value space of decimal64 is the set of numbers that can "
@@ -43,39 +47,84 @@ public class Decimal64SpecificationEffectiveStatementImpl extends
             + "'i x 10^-n' where i is an integer64 and n is an integer between 1 and 18, inclusively.";
 
     private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.3";
-    private static final BigDecimal MIN_VALUE = new BigDecimal("-922337203685477580.8");
-    private static final BigDecimal MAX_VALUE = new BigDecimal("922337203685477580.7");
+    private static final BigDecimal MIN_VALUE = new BigDecimal(
+            "-922337203685477580.8");
+    private static final BigDecimal MAX_VALUE = new BigDecimal(
+            "922337203685477580.7");
 
     private List<RangeConstraint> rangeConstraints;
     private Integer fractionDigits;
     private SchemaPath path;
+    private QName extendedTypeQName;
 
-    public Decimal64SpecificationEffectiveStatementImpl(StmtContext<String, TypeStatement.Decimal64Specification, EffectiveStatement<String, TypeStatement.Decimal64Specification>> ctx) {
-        super(ctx);
+    private ExtendedType extendedType;
+    private final boolean isExtended;
 
-        path = Utils.getSchemaPath(ctx.getParentContext()).createChild(QNAME);
+    public Decimal64SpecificationEffectiveStatementImpl(
+            StmtContext<String, TypeStatement.Decimal64Specification, EffectiveStatement<String, TypeStatement.Decimal64Specification>> ctx) {
+        super(ctx);
 
         for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
             if (effectiveStatement instanceof FractionDigitsEffectiveStatementImpl) {
-                fractionDigits = ((FractionDigitsEffectiveStatementImpl) effectiveStatement).argument();
+                fractionDigits = ((FractionDigitsEffectiveStatementImpl) effectiveStatement)
+                        .argument();
+            }
+        }
+
+        List<RangeConstraint> initRanges = initRanges();
+
+        if (!initRanges.isEmpty() && validateRanges(initRanges)) {
+            isExtended = true;
+            rangeConstraints = ImmutableList.copyOf(initRanges);
+            SchemaPath parentPath = Utils.getSchemaPath(ctx.getParentContext());
+            extendedTypeQName = QName.create(parentPath.getLastComponent().getModule(), QNAME.getLocalName());
+            path = parentPath.createChild(extendedTypeQName);
+        } else {
+            isExtended = false;
+            rangeConstraints = defaultRangeStatements();
+            path = Utils.getSchemaPath(ctx.getParentContext()).createChild(QNAME);
+        }
+    }
+
+    private boolean validateRanges(List<RangeConstraint> initRanges) {
+        for (RangeConstraint rangeConstraint : initRanges) {
+
+            String maxValueString = rangeConstraint.getMax().toString();
+            String minValueString = rangeConstraint.getMin().toString();
+
+            if ((!maxValueString.equals("max") && new BigDecimal(maxValueString)
+                    .compareTo(MAX_VALUE) > 0)
+                    || (!minValueString.equals("min") && new BigDecimal(
+                            minValueString).compareTo(MIN_VALUE) < 0)) {
+                return false;
             }
         }
-        
-        rangeConstraints = defaultRangeStatements();
+        return true;
+    }
+
+    protected List<RangeConstraint> initRanges() {
+        final RangeEffectiveStatementImpl rangeConstraints = firstEffective(RangeEffectiveStatementImpl.class);
+        return rangeConstraints != null ? rangeConstraints.argument()
+                : Collections.<RangeConstraint> emptyList();
     }
 
     private List<RangeConstraint> defaultRangeStatements() {
 
         final List<RangeConstraint> rangeStmts = new ArrayList<>();
-        final String rangeDescription = "Integer values between " + MIN_VALUE + " and " + MAX_VALUE + ", inclusively.";
+        final String rangeDescription = "Integer values between " + MIN_VALUE
+                + " and " + MAX_VALUE + ", inclusively.";
         final String rangeReference = RangeConstraintEffectiveImpl.DEFAULT_REFERENCE;
 
-        rangeStmts.add(new RangeConstraintEffectiveImpl(MIN_VALUE, MAX_VALUE, Optional.of(rangeDescription), Optional
-                .of(rangeReference)));
+        rangeStmts.add(new RangeConstraintEffectiveImpl(MIN_VALUE, MAX_VALUE,
+                Optional.of(rangeDescription), Optional.of(rangeReference)));
 
         return ImmutableList.copyOf(rangeStmts);
     }
 
+    public boolean isExtended() {
+        return isExtended;
+    }
+
     @Override
     public List<RangeConstraint> getRangeConstraints() {
         return rangeConstraints;
@@ -88,7 +137,14 @@ public class Decimal64SpecificationEffectiveStatementImpl extends
 
     @Override
     public DecimalTypeDefinition getBaseType() {
-        return null;
+        if(isExtended) {
+            if (decimal64Instance == null) {
+                decimal64Instance = Decimal64.create(path, fractionDigits);
+            }
+            return decimal64Instance;
+        } else {
+            return null;
+        }
     }
 
     @Override
@@ -164,20 +220,39 @@ public class Decimal64SpecificationEffectiveStatementImpl extends
 
     @Override
     public String toString() {
-        return Decimal64SpecificationEffectiveStatementImpl.class.getSimpleName() + "[qName=" + QNAME
-                + ", fractionDigits=" + fractionDigits + "]";
+        return Decimal64SpecificationEffectiveStatementImpl.class
+                .getSimpleName()
+                + "[qName="
+                + QNAME
+                + ", fractionDigits="
+                + fractionDigits + "]";
     }
 
     private Decimal64 decimal64Instance = null;
 
     @Override
-    public Decimal64 buildType() {
+    public TypeDefinition<?> buildType() {
 
-        if (decimal64Instance != null) {
+        if (decimal64Instance == null) {
+            decimal64Instance = Decimal64.create(path, fractionDigits);
+        }
+
+        if(!isExtended) {
             return decimal64Instance;
         }
-        decimal64Instance = Decimal64.create(path, fractionDigits);
 
-        return decimal64Instance;
+        if (extendedType != null) {
+            return extendedType;
+        }
+
+        Builder extendedTypeBuilder = ExtendedType.builder(path.getLastComponent(), decimal64Instance, Optional.<String>absent(),
+                Optional.<String>absent(), path);
+
+        extendedTypeBuilder.fractionDigits(fractionDigits);
+        extendedTypeBuilder.ranges(rangeConstraints);
+
+        extendedType = extendedTypeBuilder.build();
+
+        return extendedType;
     }
 }