Convert type checking in AbstractTypeStatementSupport
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / type / TypeStatementRFC7950Support.java
index ba61b92dec297cd85dd0d7d08e56f54997dc96b2..5f78473409beba91acc998cb7b9343dff70449fb 100644 (file)
@@ -9,7 +9,18 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.type;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableMap;
+import java.util.Optional;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.model.api.stmt.BitEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.EnumEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ValueEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 /**
  * Class providing necessary support for processing YANG 1.1 Type statement.
@@ -39,4 +50,60 @@ public final class TypeStatementRFC7950Support extends AbstractTypeStatementSupp
         final StatementSupport<?, ?, ?> potential = ARGUMENT_SPECIFIC_SUPPORTS.get(argument);
         return potential != null ? potential : super.getSupportSpecificForArgument(argument);
     }
+
+    @Override
+    Bit addRestrictedBit(final EffectiveStmtCtx stmt, final BitsTypeDefinition base, final BitEffectiveStatement bit) {
+        // FIXME: this looks like a duplicate of BitsSpecificationEffectiveStatement
+        final Optional<Uint32> declaredPosition = bit.getDeclaredPosition();
+        final Uint32 effectivePos;
+        if (declaredPosition.isEmpty()) {
+            effectivePos = getBaseTypeBitPosition(bit.argument(), base, stmt);
+        } else {
+            effectivePos = declaredPosition.get();
+        }
+
+        return EffectiveTypeUtil.buildBit(bit, effectivePos);
+    }
+
+    @Override
+    EnumPair addRestrictedEnum(final EffectiveStmtCtx stmt, final EnumTypeDefinition base,
+            final EnumEffectiveStatement enumStmt) {
+        final EnumEffectiveStatement enumSubStmt = enumStmt;
+        final Optional<Integer> declaredValue =
+                enumSubStmt.findFirstEffectiveSubstatementArgument(ValueEffectiveStatement.class);
+        final int effectiveValue;
+        if (declaredValue.isEmpty()) {
+            effectiveValue = getBaseTypeEnumValue(enumSubStmt.getDeclared().rawArgument(), base, stmt);
+        } else {
+            effectiveValue = declaredValue.orElseThrow();
+        }
+
+        return EffectiveTypeUtil.buildEnumPair(enumSubStmt, effectiveValue);
+    }
+
+    private static Uint32 getBaseTypeBitPosition(final String bitName, final BitsTypeDefinition baseType,
+            final EffectiveStmtCtx stmt) {
+        for (Bit baseTypeBit : baseType.getBits()) {
+            if (bitName.equals(baseTypeBit.getName())) {
+                return baseTypeBit.getPosition();
+            }
+        }
+
+        throw new SourceException(stmt.sourceReference(), "Bit '%s' is not a subset of its base bits type %s.", bitName,
+            baseType.getQName());
+    }
+
+
+    private static int getBaseTypeEnumValue(final String enumName, final EnumTypeDefinition baseType,
+            final EffectiveStmtCtx ctx) {
+        for (EnumPair baseTypeEnumPair : baseType.getValues()) {
+            if (enumName.equals(baseTypeEnumPair.getName())) {
+                return baseTypeEnumPair.getValue();
+            }
+        }
+
+        throw new SourceException(ctx.sourceReference(), "Enum '%s' is not a subset of its base enumeration type %s.",
+            enumName, baseType.getQName());
+    }
+
 }