X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-reactor%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fstmt%2Freactor%2FReactorStmtCtx.java;h=5e9f5983e2f2e697cb465a7798414a659adc17f4;hb=0735f709c996762a2ac65338459c465bffc4dbcf;hp=212cae9035165a40bbe7b88cc63c253340da73bc;hpb=3f5ee49aadc951c4f8f2f535561fa2880357172c;p=yangtools.git diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java index 212cae9035..5e9f5983e2 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java @@ -7,6 +7,7 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Verify.verify; import com.google.common.base.MoreObjects; @@ -19,11 +20,11 @@ import java.util.Set; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.SchemaPath; 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.meta.IdentifierNamespace; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ConfigEffectiveStatement; @@ -32,13 +33,13 @@ import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; -import org.opendaylight.yangtools.yang.parser.spi.meta.CommonStmtCtx; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; 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.ModelActionBuilder; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; -import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry; +import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace; 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; @@ -118,6 +119,13 @@ abstract class ReactorStmtCtx, E extends Effec // of this flag -- eliminating the initial alignment shadow used by below gap-filler fields. private boolean isSupportedToBuildEffective = true; + // EffectiveConfig mapping + private static final int MASK_CONFIG = 0x03; + private static final int HAVE_CONFIG = 0x04; + // Effective instantiation mechanics for StatementContextBase: if this flag is set all substatements are known not + // change when instantiated. This includes context-independent statements as well as any statements which are + // ignored during copy instantiation. + private static final int ALL_INDEPENDENT = 0x08; // Flag bit assignments private static final int IS_SUPPORTED_BY_FEATURES = 0x10; private static final int HAVE_SUPPORTED_BY_FEATURES = 0x20; @@ -127,9 +135,6 @@ abstract class ReactorStmtCtx, E extends Effec private static final int SET_SUPPORTED_BY_FEATURES = HAVE_SUPPORTED_BY_FEATURES | IS_SUPPORTED_BY_FEATURES; private static final int SET_IGNORE_IF_FEATURE = HAVE_IGNORE_IF_FEATURE | IS_IGNORE_IF_FEATURE; - // EffectiveConfig mapping - private static final int MASK_CONFIG = 0x03; - private static final int HAVE_CONFIG = 0x04; private static final EffectiveConfig[] EFFECTIVE_CONFIGS; static { @@ -149,8 +154,8 @@ abstract class ReactorStmtCtx, E extends Effec // SchemaPath cache for use with SubstatementContext and InferredStatementContext. This hurts RootStatementContext // a bit in terms of size -- but those are only a few and SchemaPath is on its way out anyway. - @Deprecated - private volatile SchemaPath schemaPath; + // FIXME: this should become 'QName' + private SchemaPath schemaPath; ReactorStmtCtx() { // Empty on purpose @@ -193,11 +198,6 @@ abstract class ReactorStmtCtx, E extends Effec getRoot().setRootVersionImpl(version); } - @Override - public final void addMutableStmtToSeal(final MutableStatement mutableStatement) { - getRoot().addMutableStmtToSealImpl(mutableStatement); - } - @Override public final void addRequiredSource(final SourceIdentifier dependency) { getRoot().addRequiredSourceImpl(dependency); @@ -229,8 +229,9 @@ abstract class ReactorStmtCtx, E extends Effec } @Override - public final CommonStmtCtx root() { - return getRoot(); + public final QName moduleName() { + final RootStatementContext root = getRoot(); + return QName.create(StmtContextUtils.getRootModuleQName(root), root.getRawArgument()); } @Override @@ -238,6 +239,23 @@ abstract class ReactorStmtCtx, E extends Effec return getOriginalCtx().map(StmtContext::buildEffective).orElse(null); } + @Override + // Non-final due to InferredStatementContext's override + public > @NonNull Optional findSubstatementArgument( + final @NonNull Class type) { + return allSubstatementsStream() + .filter(ctx -> ctx.isSupportedToBuildEffective() && ctx.producesEffective(type)) + .findAny() + .map(ctx -> (X) ctx.getArgument()); + } + + @Override + // Non-final due to InferredStatementContext's override + public boolean hasSubstatement(final @NonNull Class> type) { + return allSubstatementsStream() + .anyMatch(ctx -> ctx.isSupportedToBuildEffective() && ctx.producesEffective(type)); + } + @Override @Deprecated @SuppressWarnings("unchecked") @@ -268,32 +286,57 @@ abstract class ReactorStmtCtx, E extends Effec // @Override - public final > V namespaceItem(final Class<@NonNull N> type, + public final > V namespaceItem(final Class<@NonNull N> type, final T key) { return getBehaviourRegistry().getNamespaceBehaviour(type).getFrom(this, key); } @Override - public final > Map namespace(final Class<@NonNull N> type) { + public final > Map namespace(final Class<@NonNull N> type) { return getNamespace(type); } @Override - public final > Map localNamespace(final Class<@NonNull N> type) { + public final > + Map localNamespacePortion(final Class<@NonNull N> type) { return getLocalNamespace(type); } @Override - protected final void checkLocalNamespaceAllowed(final Class> type) { + protected final void checkLocalNamespaceAllowed(final Class> type) { definition().checkNamespaceAllowed(type); } @Override - protected > void onNamespaceElementAdded(final Class type, final K key, + protected > void onNamespaceElementAdded(final Class type, final K key, final V value) { // definition().onNamespaceElementAdded(this, type, key, value); } + /** + * Return the effective statement view of a copy operation. This method may return one of: + *
    + *
  • {@code this}, when the effective view did not change
  • + *
  • an InferredStatementContext, when there is a need for inference-equivalent copy
  • + *
  • {@code null}, when the statement failed to materialize
  • + *
+ * + * @param parent Proposed new parent + * @param type Copy operation type + * @param targetModule New target module + * @return {@link ReactorStmtCtx} holding effective view + */ + abstract @Nullable ReactorStmtCtx asEffectiveChildOf(StatementContextBase parent, CopyType type, + QNameModule targetModule); + + @Override + public final ReactorStmtCtx replicaAsChildOf(final Mutable parent) { + checkArgument(parent instanceof StatementContextBase, "Unsupported parent %s", parent); + return replicaAsChildOf((StatementContextBase) parent); + } + + abstract @NonNull ReplicaStatementContext replicaAsChildOf(@NonNull StatementContextBase parent); + // // // Statement build entry points -- both public and package-private. @@ -466,7 +509,7 @@ abstract class ReactorStmtCtx, E extends Effec return false; } - // These two exists only due to memory optimization, should live in AbstractResumedStatement. We are also reusing + // These two exist only due to memory optimization, should live in AbstractResumedStatement. We are also reusing // this for ReplicaStatementContext's refcount tracking. final boolean fullyDefined() { return fullyDefined; @@ -476,6 +519,37 @@ abstract class ReactorStmtCtx, E extends Effec fullyDefined = true; } + // These two exist only for StatementContextBase. Since we are squeezed for size, with only a single bit available + // in flags, we default to 'false' and only set the flag to true when we are absolutely sure -- and all other cases + // err on the side of caution by taking the time to evaluate each substatement separately. + final boolean allSubstatementsContextIndependent() { + return (flags & ALL_INDEPENDENT) != 0; + } + + final void setAllSubstatementsContextIndependent() { + flags |= ALL_INDEPENDENT; + } + + // + // + // Various functionality from AbstractTypeStatementSupport. This used to work on top of SchemaPath, now it still + // lives here. Ultimate future is either proper graduation or (more likely) move to AbstractTypeStatementSupport. + // + // + + @Override + public final QName argumentAsTypeQName() { + final Object argument = argument(); + verify(argument instanceof String, "Unexpected argument %s", argument); + return interpretAsQName((String) argument); + } + + @Override + public final QNameModule effectiveNamespace() { + // FIXME: there has to be a better way to do this + return getSchemaPath().getLastComponent().getModule(); + } + // // // Common SchemaPath cache. All of this is bound to be removed once YANGTOOLS-1066 is done. @@ -484,26 +558,17 @@ abstract class ReactorStmtCtx, E extends Effec // Exists only to support {SubstatementContext,InferredStatementContext}.schemaPath() @Deprecated - final @NonNull Optional substatementGetSchemaPath() { - SchemaPath local = schemaPath; - if (local == null) { - synchronized (this) { - local = schemaPath; - if (local == null) { - schemaPath = local = createSchemaPath((StatementContextBase) coerceParentContext()); - } - } + final @Nullable SchemaPath substatementGetSchemaPath() { + if (schemaPath == null) { + schemaPath = createSchemaPath((StatementContextBase) coerceParentContext()); } - - return Optional.ofNullable(local); + return schemaPath; } + // FIXME: 7.0.0: this method's logic needs to be moved to the respective StatementSupport classes @Deprecated private SchemaPath createSchemaPath(final StatementContextBase parent) { - final Optional maybeParentPath = parent.schemaPath(); - verify(maybeParentPath.isPresent(), "Parent %s does not have a SchemaPath", parent); - final SchemaPath parentPath = maybeParentPath.get(); - + final SchemaPath parentPath = parent.getSchemaPath(); if (StmtContextUtils.isUnknownStatement(this)) { return parentPath.createChild(publicDefinition().getStatementName()); } @@ -511,16 +576,13 @@ abstract class ReactorStmtCtx, E extends Effec if (argument instanceof QName) { final QName qname = (QName) argument; if (producesDeclared(UsesStatement.class)) { - return maybeParentPath.orElse(null); + return parentPath; } return parentPath.createChild(qname); } if (argument instanceof String) { - // FIXME: This may yield illegal argument exceptions - final Optional> originalCtx = getOriginalCtx(); - final QName qname = StmtContextUtils.qnameFromArgument(originalCtx.orElse(this), (String) argument); - return parentPath.createChild(qname); + return parentPath.createChild(interpretAsQName((String) argument)); } if (argument instanceof SchemaNodeIdentifier && (producesDeclared(AugmentStatement.class) || producesDeclared(RefineStatement.class) @@ -529,8 +591,13 @@ abstract class ReactorStmtCtx, E extends Effec return parentPath.createChild(((SchemaNodeIdentifier) argument).getNodeIdentifiers()); } - // FIXME: this does not look right - return maybeParentPath.orElse(null); + // FIXME: this does not look right, investigate more? + return parentPath; + } + + private @NonNull QName interpretAsQName(final String argument) { + // FIXME: This may yield illegal argument exceptions + return StmtContextUtils.qnameFromArgument(getOriginalCtx().orElse(this), argument); } // @@ -593,6 +660,15 @@ abstract class ReactorStmtCtx, E extends Effec } } + /** + * Return {@code true} if this context has an outstanding reference. + * + * @return True if this context has an outstanding reference. + */ + final boolean haveRef() { + return refcount > REFCOUNT_NONE; + } + private void lastDecRef() { if (noImplictRef()) { // We are no longer guarded by effective instance