*/
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.type;
+import static com.google.common.base.Verify.verifyNotNull;
+
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
import java.math.BigDecimal;
import java.util.Collection;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.type.BitsTypeBuilder;
-import org.opendaylight.yangtools.yang.model.util.type.EnumerationTypeBuilder;
-import org.opendaylight.yangtools.yang.model.util.type.InstanceIdentifierTypeBuilder;
-import org.opendaylight.yangtools.yang.model.util.type.InvalidLengthConstraintException;
-import org.opendaylight.yangtools.yang.model.util.type.InvalidRangeConstraintException;
-import org.opendaylight.yangtools.yang.model.util.type.LengthRestrictedTypeBuilder;
-import org.opendaylight.yangtools.yang.model.util.type.RangeRestrictedTypeBuilder;
-import org.opendaylight.yangtools.yang.model.util.type.RequireInstanceRestrictedTypeBuilder;
-import org.opendaylight.yangtools.yang.model.util.type.RestrictedTypes;
-import org.opendaylight.yangtools.yang.model.util.type.StringTypeBuilder;
+import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements;
+import org.opendaylight.yangtools.yang.model.ri.type.BitsTypeBuilder;
+import org.opendaylight.yangtools.yang.model.ri.type.EnumerationTypeBuilder;
+import org.opendaylight.yangtools.yang.model.ri.type.InstanceIdentifierTypeBuilder;
+import org.opendaylight.yangtools.yang.model.ri.type.InvalidLengthConstraintException;
+import org.opendaylight.yangtools.yang.model.ri.type.InvalidRangeConstraintException;
+import org.opendaylight.yangtools.yang.model.ri.type.LengthRestrictedTypeBuilder;
+import org.opendaylight.yangtools.yang.model.ri.type.RangeRestrictedTypeBuilder;
+import org.opendaylight.yangtools.yang.model.ri.type.RequireInstanceRestrictedTypeBuilder;
+import org.opendaylight.yangtools.yang.model.ri.type.RestrictedTypes;
+import org.opendaylight.yangtools.yang.model.ri.type.StringTypeBuilder;
import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStringStatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
abstract class AbstractTypeStatementSupport
- extends AbstractStatementSupport<String, TypeStatement, EffectiveStatement<String, TypeStatement>> {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractTypeStatementSupport.class);
-
+ extends AbstractStringStatementSupport<TypeStatement, EffectiveStatement<String, TypeStatement>> {
private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(
YangStmtMapping.TYPE)
.addOptional(YangStmtMapping.BASE)
static final String UINT64 = "uint64";
static final String UNION = "union";
- private static final ImmutableMap<String, String> BUILT_IN_TYPES = ImmutableMap.<String, String>builder()
- .put(BINARY, BINARY)
- .put(BITS, BITS)
- .put(BOOLEAN, BOOLEAN)
- .put(DECIMAL64, DECIMAL64)
- .put(EMPTY, EMPTY)
- .put(ENUMERATION, ENUMERATION)
- .put(IDENTITY_REF,IDENTITY_REF)
- .put(INSTANCE_IDENTIFIER, INSTANCE_IDENTIFIER)
- .put(INT8, INT8)
- .put(INT16, INT16)
- .put(INT32, INT32)
- .put(INT64, INT64)
- .put(LEAF_REF, LEAF_REF)
- .put(STRING, STRING)
- .put(UINT8, UINT8)
- .put(UINT16, UINT16)
- .put(UINT32, UINT32)
- .put(UINT64, UINT64)
- .put(UNION, UNION)
- .build();
+ private static final ImmutableMap<String, BuiltinEffectiveStatement> STATIC_BUILT_IN_TYPES =
+ ImmutableMap.<String, BuiltinEffectiveStatement>builder()
+ .put(BINARY, BuiltinEffectiveStatement.BINARY)
+ .put(BOOLEAN, BuiltinEffectiveStatement.BOOLEAN)
+ .put(EMPTY, BuiltinEffectiveStatement.EMPTY)
+ // FIXME: this overlaps with DYNAMIC_BUILT_IN_TYPES. One of these is not needed, but we need to decide
+ // what to do. I think we should gradually use per-statement validators, hence go towards dynamic?
+ .put(INSTANCE_IDENTIFIER, BuiltinEffectiveStatement.INSTANCE_IDENTIFIER)
+ .put(INT8, BuiltinEffectiveStatement.INT8)
+ .put(INT16, BuiltinEffectiveStatement.INT16)
+ .put(INT32, BuiltinEffectiveStatement.INT32)
+ .put(INT64, BuiltinEffectiveStatement.INT64)
+ .put(STRING, BuiltinEffectiveStatement.STRING)
+ .put(UINT8, BuiltinEffectiveStatement.UINT8)
+ .put(UINT16, BuiltinEffectiveStatement.UINT16)
+ .put(UINT32, BuiltinEffectiveStatement.UINT32)
+ .put(UINT64, BuiltinEffectiveStatement.UINT64)
+ .build();
- private static final ImmutableMap<String, StatementSupport<?, ?, ?>> ARGUMENT_SPECIFIC_SUPPORTS =
+ private static final ImmutableMap<String, StatementSupport<?, ?, ?>> DYNAMIC_BUILT_IN_TYPES =
ImmutableMap.<String, StatementSupport<?, ?, ?>>builder()
.put(BITS, new BitsSpecificationSupport())
.put(DECIMAL64, new Decimal64SpecificationSupport())
.put(UNION, new UnionSpecificationSupport())
.build();
- AbstractTypeStatementSupport() {
- // FIXME: can a type statement be copied?
- super(YangStmtMapping.TYPE, StatementPolicy.legacyDeclaredCopy());
- }
+ private static final ImmutableMap<String, String> BUILT_IN_TYPES = Maps.uniqueIndex(ImmutableSet.copyOf(
+ Iterables.<String>concat(STATIC_BUILT_IN_TYPES.keySet(), DYNAMIC_BUILT_IN_TYPES.keySet())), key -> key);
- @Override
- public final String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
- return value;
+ AbstractTypeStatementSupport() {
+ super(YangStmtMapping.TYPE, StatementPolicy.exactReplica());
}
@Override
final Mutable<String, TypeStatement, EffectiveStatement<String, TypeStatement>> stmt) {
super.onFullDefinitionDeclared(stmt);
- // if it is yang built-in type, no prerequisite is needed, so simply return
- if (BUILT_IN_TYPES.containsKey(stmt.argument())) {
- // FIXME: consider populating BaseTypeNamespace here, which could be done quite efficiently, moving the
- // logic from resolveType()
+ final String argument = stmt.getArgument();
+ final BuiltinEffectiveStatement builtin = STATIC_BUILT_IN_TYPES.get(argument);
+ if (builtin != null) {
+ stmt.addToNs(BaseTypeNamespace.class, Empty.getInstance(), builtin);
return;
}
- final QName typeQName = StmtContextUtils.parseNodeIdentifier(stmt, stmt.argument());
+ final QName typeQName = StmtContextUtils.parseNodeIdentifier(stmt, argument);
final ModelActionBuilder typeAction = stmt.newInferenceAction(ModelProcessingPhase.EFFECTIVE_MODEL);
final Prerequisite<StmtContext<?, ?, ?>> typePrereq = typeAction.requiresCtx(stmt, TypeNamespace.class,
typeQName, ModelProcessingPhase.EFFECTIVE_MODEL);
typeAction.apply(new InferenceAction() {
@Override
public void apply(final InferenceContext ctx) {
+ // Note: do not attempt to call buildEffective() here
stmt.addToNs(BaseTypeNamespace.class, Empty.getInstance(), typePrereq.resolve(ctx));
}
@Override
public boolean hasArgumentSpecificSupports() {
- return !ARGUMENT_SPECIFIC_SUPPORTS.isEmpty();
+ return !DYNAMIC_BUILT_IN_TYPES.isEmpty();
}
@Override
public StatementSupport<?, ?, ?> getSupportSpecificForArgument(final String argument) {
- return ARGUMENT_SPECIFIC_SUPPORTS.get(argument);
+ return DYNAMIC_BUILT_IN_TYPES.get(argument);
}
@Override
@Override
protected final TypeStatement createDeclared(final StmtContext<String, TypeStatement, ?> ctx,
final ImmutableList<? extends DeclaredStatement<?>> substatements) {
- return new RegularTypeStatement(ctx.getRawArgument(), substatements);
+ return DeclaredStatements.createType(ctx.getRawArgument(), substatements);
}
@Override
protected final TypeStatement createEmptyDeclared(final StmtContext<String, TypeStatement, ?> ctx) {
final TypeStatement builtin;
return (builtin = BuiltinTypeStatement.lookup(ctx)) != null ? builtin
- : new EmptyTypeStatement(ctx.getRawArgument());
+ : DeclaredStatements.createType(ctx.getRawArgument());
}
@Override
}
}
+ // FIXME: YANGTOOLS-1208: this needs to happen during onFullDefinitionDeclared() and stored (again) in a namespace
static final @NonNull QName typeEffectiveQName(final Current<String, ?> stmt) {
- // FIXME: this really should be handled through A=AbstractQName, with two values coming out of parseArgument():
- // -- either UnqualifiedQName or QualifiedQName. Each of those can easily be bound to parent module:
- // stmt.getArgument().bindTo(parentNamespace). We could perhaps also make it a QName and deal with this
- // bit during adaptArgument().
+ // FIXME: YANGTOOLS-1117: this really should be handled through A=AbstractQName, with two values coming out of
+ // parseArgument(): either UnqualifiedQName or QualifiedQName. Each of those can easily be bound to
+ // parent module:
+ // stmt.getArgument().bindTo(parentNamespace).
final String argument = stmt.getArgument();
return QName.create(stmt.getEffectiveParent().effectiveNamespace(),
// Split out localName event if it is prefixed. This should really be in parseArgument()
* @throws SourceException if the target type cannot be found
*/
private static @NonNull TypeEffectiveStatement<TypeStatement> resolveType(final Current<String, ?> ctx) {
- final StmtContext<?, ?, ?> baseType = ctx.namespaceItem(BaseTypeNamespace.class, Empty.getInstance());
- if (baseType != null) {
- return ((TypedefEffectiveStatement) baseType.buildEffective()).asTypeEffectiveStatement();
- }
-
- final String argument = ctx.getArgument();
- switch (argument) {
- case BINARY:
- return BuiltinEffectiveStatement.BINARY;
- case BOOLEAN:
- return BuiltinEffectiveStatement.BOOLEAN;
- case EMPTY:
- return BuiltinEffectiveStatement.EMPTY;
- case INSTANCE_IDENTIFIER:
- return BuiltinEffectiveStatement.INSTANCE_IDENTIFIER;
- case INT8:
- return BuiltinEffectiveStatement.INT8;
- case INT16:
- return BuiltinEffectiveStatement.INT16;
- case INT32:
- return BuiltinEffectiveStatement.INT32;
- case INT64:
- return BuiltinEffectiveStatement.INT64;
- case STRING:
- return BuiltinEffectiveStatement.STRING;
- case UINT8:
- return BuiltinEffectiveStatement.UINT8;
- case UINT16:
- return BuiltinEffectiveStatement.UINT16;
- case UINT32:
- return BuiltinEffectiveStatement.UINT32;
- case UINT64:
- return BuiltinEffectiveStatement.UINT64;
- default:
- throw new IllegalStateException("Unhandled type argument " + argument);
+ final Object obj = verifyNotNull(ctx.namespaceItem(BaseTypeNamespace.class, Empty.getInstance()));
+ if (obj instanceof BuiltinEffectiveStatement) {
+ return (BuiltinEffectiveStatement) obj;
+ } else if (obj instanceof StmtContext) {
+ return ((TypedefEffectiveStatement) ((StmtContext<?, ?, ?>) obj).buildEffective())
+ .asTypeEffectiveStatement();
+ } else {
+ throw new InferenceException(ctx, "Unexpected base object %s", obj);
}
}