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 / TypeDefEffectiveStatementImpl.java
index ee0ec2007a91e7ca7f39fd9f7476266bd7b1f7c5..fe9e1389c70f88b58abed5acfddce84866e01e02 100644 (file)
@@ -7,6 +7,14 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
+
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.Decimal64SpecificationEffectiveStatementImpl;
+import java.util.ArrayList;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.LengthEffectiveStatementImpl;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.PatternEffectiveStatementImpl;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.RangeEffectiveStatementImpl;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 import java.util.Collections;
@@ -17,7 +25,6 @@ import org.opendaylight.yangtools.yang.model.api.Status;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
@@ -26,12 +33,12 @@ import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.util.ExtendedType.Builder;
 import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.TypeDefinitionEffectiveBuilder;
 
-public class TypeDefEffectiveStatementImpl extends EffectiveStatementBase<QName, TypedefStatement> implements
+public class TypeDefEffectiveStatementImpl extends
+        EffectiveStatementBase<QName, TypedefStatement> implements
         TypeDefinition<TypeDefinition<?>>, TypeDefinitionEffectiveBuilder {
 
     private final QName qName;
@@ -54,72 +61,132 @@ public class TypeDefEffectiveStatementImpl extends EffectiveStatementBase<QName,
 
     private ExtendedType extendedType = null;
 
-    public TypeDefEffectiveStatementImpl(StmtContext<QName, TypedefStatement, ?> ctx) {
+    public TypeDefEffectiveStatementImpl(
+            StmtContext<QName, TypedefStatement, ?> ctx) {
         super(ctx);
 
         qName = ctx.getStatementArgument();
         path = Utils.getSchemaPath(ctx);
+        baseType = parseBaseTypeFromCtx(ctx);
+
+        EffectiveStatementBase<?, ?> typeEffectiveStmt = firstSubstatementOfType(
+                TypeDefinition.class, EffectiveStatementBase.class);
+
+        ranges = initRanges(typeEffectiveStmt);
+        lengths = initLengths(typeEffectiveStmt);
+        patterns = initPatterns(typeEffectiveStmt);
 
-        ExtendedTypeEffectiveStatementImpl type = null;
+        //due to compatibility problems with original yang parser
+        //:FIXME try to find out better solution
+        if (typeEffectiveStmt.argument().equals(TypeUtils.DECIMAL64)
+                && ranges.isEmpty()) {
+            fractionDigits = null;
+        } else {
+            fractionDigits = initFractionDigits(typeEffectiveStmt);
+        }
 
         for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
-            if (effectiveStatement instanceof ExtendedTypeEffectiveStatementImpl) {
-                type = ((ExtendedTypeEffectiveStatementImpl) effectiveStatement);
-            }
             if (effectiveStatement instanceof DefaultEffectiveStatementImpl) {
-                defaultValue = ((DefaultEffectiveStatementImpl) effectiveStatement).argument();
+                defaultValue = ((DefaultEffectiveStatementImpl) effectiveStatement)
+                        .argument();
             }
             if (effectiveStatement instanceof UnitsEffectiveStatementImpl) {
-                units = ((UnitsEffectiveStatementImpl) effectiveStatement).argument();
+                units = ((UnitsEffectiveStatementImpl) effectiveStatement)
+                        .argument();
             }
             if (effectiveStatement instanceof DescriptionEffectiveStatementImpl) {
-                description = ((DescriptionEffectiveStatementImpl) effectiveStatement).argument();
+                description = ((DescriptionEffectiveStatementImpl) effectiveStatement)
+                        .argument();
             }
             if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) {
-                reference = ((ReferenceEffectiveStatementImpl) effectiveStatement).argument();
+                reference = ((ReferenceEffectiveStatementImpl) effectiveStatement)
+                        .argument();
             }
             if (effectiveStatement instanceof StatusEffectiveStatementImpl) {
-                status = ((StatusEffectiveStatementImpl) effectiveStatement).argument();
+                status = ((StatusEffectiveStatementImpl) effectiveStatement)
+                        .argument();
             }
         }
+    }
 
-        if (type != null) {
+    private TypeDefinition<?> parseBaseTypeFromCtx(
+            final StmtContext<QName, TypedefStatement, ?> ctx) {
 
-            ranges = ImmutableList.copyOf(type.getRangeConstraints());
-            lengths = ImmutableList.copyOf(type.getLengthConstraints());
-            patterns = ImmutableList.copyOf(type.getPatternConstraints());
-            fractionDigits = type.getFractionDigits();
-        } else {
+        TypeDefinition<?> baseType;
 
-            ranges = Collections.emptyList();
-            lengths = Collections.emptyList();
-            patterns = Collections.emptyList();
-            fractionDigits = null;
+        QName baseTypeQName = Utils.qNameFromArgument(ctx, StmtContextUtils
+                .firstAttributeOf(ctx.declaredSubstatements(),
+                        TypeStatement.class));
+
+        if (TypeUtils.isYangBuiltInTypeString(baseTypeQName.getLocalName())) {
+            baseType = TypeUtils.getYangPrimitiveTypeFromString(baseTypeQName
+                    .getLocalName());
+            if (baseType == null) {
+                baseType = firstSubstatementOfType(TypeDefinition.class);
+
+                //due to compatibility problems with original yang parser
+                //:FIXME try to find out better solution
+                if(baseType instanceof Decimal64SpecificationEffectiveStatementImpl) {
+                    Decimal64SpecificationEffectiveStatementImpl decimal64 = (Decimal64SpecificationEffectiveStatementImpl) baseType;
+                    if(decimal64.isExtended()) {
+                        baseType = decimal64.getBaseType();
+                    }
+                }
+            }
+        } else {
+            StmtContext<?, TypedefStatement, EffectiveStatement<QName, TypedefStatement>> baseTypeCtx = ctx
+                    .getParentContext().getFromNamespace(TypeNamespace.class,
+                            baseTypeQName);
+            baseType = (TypeDefEffectiveStatementImpl) baseTypeCtx
+                    .buildEffective();
         }
 
-        baseType = parseBaseTypeFromCtx(ctx);
+        return baseType;
     }
 
-    private TypeDefinition<?> parseBaseTypeFromCtx(final StmtContext<QName, TypedefStatement, ?> ctx) {
+    protected Integer initFractionDigits(
+            EffectiveStatementBase<?, ?> typeEffectiveStmt) {
+        final FractionDigitsEffectiveStatementImpl fractionDigitsEffStmt = typeEffectiveStmt
+                .firstEffective(FractionDigitsEffectiveStatementImpl.class);
+        return fractionDigitsEffStmt != null ? fractionDigitsEffStmt.argument()
+                : null;
+    }
 
-        TypeDefinition<?> baseType;
+    protected List<RangeConstraint> initRanges(
+            EffectiveStatementBase<?, ?> typeEffectiveStmt) {
+        final RangeEffectiveStatementImpl rangeConstraints = typeEffectiveStmt
+                .firstEffective(RangeEffectiveStatementImpl.class);
+        return rangeConstraints != null ? rangeConstraints.argument()
+                : Collections.<RangeConstraint> emptyList();
+    }
 
-        QName baseTypeQName = Utils.qNameFromArgument(ctx,
-                StmtContextUtils.firstAttributeOf(ctx.declaredSubstatements(), TypeStatement.class));
+    protected List<LengthConstraint> initLengths(
+            EffectiveStatementBase<?, ?> typeEffectiveStmt) {
+        final LengthEffectiveStatementImpl lengthConstraints = typeEffectiveStmt
+                .firstEffective(LengthEffectiveStatementImpl.class);
+        return lengthConstraints != null ? lengthConstraints.argument()
+                : Collections.<LengthConstraint> emptyList();
+    }
 
-        if (TypeUtils.isYangBaseTypeString(baseTypeQName.getLocalName())) {
-            baseType = TypeUtils.getYangBaseTypeFromString(baseTypeQName.getLocalName());
-        } else {
-            StmtContext<?, TypedefStatement, EffectiveStatement<QName, TypedefStatement>> baseTypeCtx = ctx
-                    .getParentContext().getFromNamespace(TypeNamespace.class, baseTypeQName);
-            baseType = (TypeDefEffectiveStatementImpl) baseTypeCtx.buildEffective();
-        }
+    protected List<PatternConstraint> initPatterns(
+            EffectiveStatementBase<?, ?> typeEffectiveStmt) {
+        final List<PatternConstraint> patternConstraints = new ArrayList<>();
 
-        if (baseType == null) {
-            baseType = firstSubstatementOfType(TypeDefinition.class);
+        for (final EffectiveStatement<?, ?> effectiveStatement : typeEffectiveStmt
+                .effectiveSubstatements()) {
+            if (effectiveStatement instanceof PatternEffectiveStatementImpl) {
+                final PatternConstraint pattern = ((PatternEffectiveStatementImpl) effectiveStatement)
+                        .argument();
+
+                if (pattern != null) {
+                    patternConstraints.add(pattern);
+                }
+            }
         }
 
-        return baseType;
+        return !patternConstraints.isEmpty() ? ImmutableList
+                .copyOf(patternConstraints) : Collections
+                .<PatternConstraint> emptyList();
     }
 
     @Override
@@ -193,10 +260,13 @@ public class TypeDefEffectiveStatementImpl extends EffectiveStatementBase<QName,
         Builder extendedTypeBuilder;
         if (baseType instanceof TypeDefinitionEffectiveBuilder) {
             TypeDefinitionEffectiveBuilder typeDefBaseType = (TypeDefinitionEffectiveBuilder) baseType;
-            extendedTypeBuilder = ExtendedType.builder(qName, typeDefBaseType.buildType(),
-                    Optional.fromNullable(description), Optional.fromNullable(reference), path);
+            extendedTypeBuilder = ExtendedType.builder(qName,
+                    typeDefBaseType.buildType(),
+                    Optional.fromNullable(description),
+                    Optional.fromNullable(reference), path);
         } else {
-            extendedTypeBuilder = ExtendedType.builder(qName, baseType, Optional.fromNullable(description),
+            extendedTypeBuilder = ExtendedType.builder(qName, baseType,
+                    Optional.fromNullable(description),
                     Optional.fromNullable(reference), path);
         }