X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-rfc7950%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frfc7950%2Fstmt%2Ftypedef%2FTypedefStatementSupport.java;h=f929ee3f116f8e1bb7f8869c523f52069acc94c9;hb=a9c6528602b30a65af8aa6afc89e465f202ef129;hp=cff14d437c9eefef33b6b70089b750b02ef0702b;hpb=7bb6ae1269659c12efc127b97cc750ed81ecaac6;p=yangtools.git diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java index cff14d437c..f929ee3f11 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefStatementSupport.java @@ -7,12 +7,30 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.typedef; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.collect.ImmutableList; +import java.util.Collection; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.DefaultEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseQNameStatementSupport; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.EffectiveStatementWithFlags.FlagsBuilder; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStmtUtils; import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport; +import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; @@ -20,7 +38,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; public final class TypedefStatementSupport extends - AbstractQNameStatementSupport { + BaseQNameStatementSupport { private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder( YangStmtMapping.TYPEDEF) .addOptional(YangStmtMapping.DEFAULT) @@ -33,7 +51,7 @@ public final class TypedefStatementSupport extends private static final TypedefStatementSupport INSTANCE = new TypedefStatementSupport(); private TypedefStatementSupport() { - super(YangStmtMapping.TYPEDEF); + super(YangStmtMapping.TYPEDEF, StatementPolicy.reject()); } public static TypedefStatementSupport getInstance() { @@ -46,51 +64,82 @@ public final class TypedefStatementSupport extends } @Override - public TypedefStatement createDeclared(final StmtContext ctx) { - // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to ensure - // that a typedef in child scope does not shadow a typedef in parent scope which occurs later in the text. - final StmtContext parent = ctx.getParentContext(); + public void onFullDefinitionDeclared(final Mutable stmt) { + super.onFullDefinitionDeclared(stmt); + + final Mutable parent = stmt.getParentContext(); if (parent != null) { + // Shadowing check: make sure we do not trample on pre-existing definitions. This catches sibling + // declarations and parent declarations which have already been declared. + checkConflict(parent, stmt); + parent.addContext(TypeNamespace.class, stmt.getArgument(), stmt); + final StmtContext grandParent = parent.getParentContext(); if (grandParent != null) { - checkConflict(grandParent, ctx); + // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to + // ensure that a typedef in child scope does not shadow a typedef in parent scope which occurs later in + // the text. For that check we need the full declaration of our model. + + final ModelActionBuilder action = stmt.newInferenceAction(ModelProcessingPhase.FULL_DECLARATION); + action.requiresCtx(grandParent.getRoot(), ModelProcessingPhase.FULL_DECLARATION); + action.apply(new InferenceAction() { + @Override + public void apply(final InferenceContext ctx) { + checkConflict(grandParent, stmt); + } + + @Override + public void prerequisiteFailed(final Collection> failed) { + // No-op + } + }); } } - - return new TypedefStatementImpl(ctx); } @Override - public TypedefEffectiveStatement createEffective( - final StmtContext ctx) { - return new TypedefEffectiveStatementImpl(ctx); + protected SubstatementValidator getSubstatementValidator() { + return SUBSTATEMENT_VALIDATOR; } @Override - public void onFullDefinitionDeclared(final Mutable stmt) { - super.onFullDefinitionDeclared(stmt); + protected TypedefStatement createDeclared(final StmtContext ctx, + final ImmutableList> substatements) { + return new RegularTypedefStatement(ctx.getArgument(), substatements); + } - if (stmt != null) { - final Mutable parent = stmt.getParentContext(); - if (parent != null) { - // Shadowing check: make sure we do not trample on pre-existing definitions. This catches sibling - // declarations and parent declarations which have already been declared. - checkConflict(parent, stmt); - parent.addContext(TypeNamespace.class, stmt.coerceStatementArgument(), stmt); - } - } + @Override + protected TypedefStatement createEmptyDeclared(final StmtContext ctx) { + return new EmptyTypedefStatement(ctx.getArgument()); } @Override - protected SubstatementValidator getSubstatementValidator() { - return SUBSTATEMENT_VALIDATOR; + protected TypedefEffectiveStatement createEffective(final Current stmt, + final ImmutableList> substatements) { + final TypedefStatement declared = stmt.declared(); + checkState(!substatements.isEmpty(), "Refusing to create empty typedef for %s", stmt.declared()); + + final TypeEffectiveStatement typeEffectiveStmt = findFirstStatement(substatements, + TypeEffectiveStatement.class); + final String dflt = findFirstArgument(substatements, DefaultEffectiveStatement.class, null); + SourceException.throwIf( + EffectiveStmtUtils.hasDefaultValueMarkedWithIfFeature(stmt.yangVersion(), typeEffectiveStmt, dflt), stmt, + "Typedef '%s' has default value '%s' marked with an if-feature statement.", stmt.argument(), dflt); + + return new TypedefEffectiveStatementImpl(declared, stmt.wrapSchemaPath(), computeFlags(substatements), + substatements); } private static void checkConflict(final StmtContext parent, final StmtContext stmt) { - final QName arg = stmt.coerceStatementArgument(); + final QName arg = stmt.getArgument(); final StmtContext existing = parent.getFromNamespace(TypeNamespace.class, arg); // RFC7950 sections 5.5 and 6.2.1: identifiers must not be shadowed - SourceException.throwIf(existing != null, stmt.getStatementSourceReference(), "Duplicate name for typedef %s", - arg); + SourceException.throwIf(existing != null, stmt, "Duplicate name for typedef %s", arg); + } + + private static int computeFlags(final ImmutableList> substatements) { + return new FlagsBuilder() + .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT)) + .toFlags(); } } \ No newline at end of file