package org.opendaylight.yangtools.yang.parser.stmt.reactor;
import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
import java.util.Collection;
import java.util.Optional;
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.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
*/
abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
extends StatementContextBase<A, D, E> implements ResumedStatement {
+ private final @NonNull StatementSourceReference statementDeclSource;
+ private final StmtContext<?, ?, ?> originalCtx;
+ private final StmtContext<?, ?, ?> prevCopyCtx;
+ private final String rawArgument;
+
private StatementMap substatements = StatementMap.empty();
+ AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
+ super(original);
+ this.statementDeclSource = original.statementDeclSource;
+ this.rawArgument = original.rawArgument;
+ this.originalCtx = original.getOriginalCtx().orElse(original);
+ this.prevCopyCtx = original;
+ this.substatements = original.substatements;
+ }
+
AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
final String rawArgument) {
- super(def, ref, rawArgument);
+ super(def);
+ this.statementDeclSource = requireNonNull(ref);
+ this.rawArgument = def.internArgument(rawArgument);
+ this.originalCtx = null;
+ this.prevCopyCtx = null;
}
AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
final String rawArgument, final CopyType copyType) {
- super(def, ref, rawArgument, copyType);
+ super(def, CopyHistory.of(copyType, CopyHistory.original()));
+ this.statementDeclSource = requireNonNull(ref);
+ this.rawArgument = rawArgument;
+ this.originalCtx = null;
+ this.prevCopyCtx = null;
}
- AbstractResumedStatement(final StatementContextBase<A, D, E> original, final CopyType copyType) {
- super(original, copyType);
+ @Override
+ public final Optional<StmtContext<?, ?, ?>> getOriginalCtx() {
+ return Optional.ofNullable(originalCtx);
}
- AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
- super(original);
- this.substatements = original.substatements;
+ @Override
+ public final Optional<? extends StmtContext<?, ?, ?>> getPreviousCopyCtx() {
+ return Optional.ofNullable(prevCopyCtx);
}
@Override
- public Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
- return substatements.values();
+ public final StatementSourceReference getStatementSourceReference() {
+ return statementDeclSource;
+ }
+
+ @Override
+ public final String rawStatementArgument() {
+ return rawArgument;
}
@Override
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.stmt.reactor;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+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.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A statement which has been inferred to exist. Functionally it is equivalent to a SubstatementContext, but it is not
+ * backed by a declaration (and declared statements). It is backed by a prototype StatementContextBase and has only
+ * effective substatements, which are either transformed from that prototype or added by inference.
+ */
+final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
+ extends StatementContextBase<A, D, E> {
+ private static final Logger LOG = LoggerFactory.getLogger(InferredStatementContext.class);
+
+ private final @NonNull StatementContextBase<A, D, E> prototype;
+ private final @NonNull StatementContextBase<?, ?, ?> parent;
+ private final @NonNull CopyType childCopyType;
+ private final QNameModule targetModule;
+ private final A argument;
+
+ private InferredStatementContext(final InferredStatementContext<A, D, E> original,
+ final StatementContextBase<?, ?, ?> parent) {
+ super(original);
+ this.parent = requireNonNull(parent);
+ this.childCopyType = original.childCopyType;
+ this.targetModule = original.targetModule;
+ this.prototype = original.prototype;
+ this.argument = original.argument;
+ }
+
+ InferredStatementContext(final StatementContextBase<?, ?, ?> parent, final StatementContextBase<A, D, E> prototype,
+ final CopyType myCopyType, final CopyType childCopyType, final QNameModule targetModule) {
+ super(prototype.definition(), CopyHistory.of(myCopyType, prototype.getCopyHistory()));
+ this.parent = requireNonNull(parent);
+ this.prototype = requireNonNull(prototype);
+ this.argument = targetModule == null ? prototype.getStatementArgument()
+ : prototype.definition().adaptArgumentValue(prototype, targetModule);
+ this.childCopyType = requireNonNull(childCopyType);
+ this.targetModule = targetModule;
+
+ // FIXME: YANGTOOLS-784: instantiate these lazily
+ addEffectiveSubstatements(createEffective());
+ }
+
+ @Override
+ public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
+ return ImmutableList.of();
+ }
+
+ @Override
+ public Iterable<? extends StmtContext<?, ?, ?>> allSubstatements() {
+ // No need to concat with declared
+ return effectiveSubstatements();
+ }
+
+ @Override
+ public Stream<? extends StmtContext<?, ?, ?>> allSubstatementsStream() {
+ // No need to concat with declared
+ return effectiveSubstatements().stream();
+ }
+
+ @Override
+ public StatementSourceReference getStatementSourceReference() {
+ return prototype.getStatementSourceReference();
+ }
+
+ @Override
+ public String rawStatementArgument() {
+ return prototype.rawStatementArgument();
+ }
+
+ @Override
+ public Optional<StmtContext<?, ?, ?>> getOriginalCtx() {
+ final Optional<StmtContext<?, ?, ?>> orig = prototype.getOriginalCtx();
+ return orig.isPresent() ? orig : Optional.of(prototype);
+ }
+
+ @Override
+ public Optional<? extends StmtContext<?, ?, ?>> getPreviousCopyCtx() {
+ return Optional.of(prototype);
+ }
+
+ @Override
+ InferredStatementContext<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
+ return new InferredStatementContext<>(this, newParent);
+ }
+
+ // Instantiate this statement's effective substatements. Note this method has side-effects in namespaces and overall
+ // BuildGlobalContext, hence it must be called at most once.
+ private List<Mutable<?, ?, ?>> createEffective() {
+ final Collection<? extends StatementContextBase<?, ?, ?>> declared = prototype.mutableDeclaredSubstatements();
+ final Collection<? extends Mutable<?, ?, ?>> effective = prototype.mutableEffectiveSubstatements();
+ final List<Mutable<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size());
+
+ for (final Mutable<?, ?, ?> stmtContext : declared) {
+ if (stmtContext.isSupportedByFeatures()) {
+ copySubstatement(stmtContext, buffer);
+ }
+ }
+ for (final Mutable<?, ?, ?> stmtContext : effective) {
+ copySubstatement(stmtContext, buffer);
+ }
+
+ return buffer;
+ }
+
+ // Statement copy mess starts here
+ //
+ // FIXME: This is messy and is probably wrong in some corner case. Even if it is correct, the way how it is correct
+ // relies on hard-coded maps. At the end of the day, the logic needs to be controlled by statement's
+ // StatementSupport.
+ // FIXME: YANGTOOLS-652: these maps look very much like those in UsesStatementImpl
+ private static final ImmutableSet<YangStmtMapping> REUSED_DEF_SET = ImmutableSet.of(
+ YangStmtMapping.TYPE,
+ YangStmtMapping.TYPEDEF,
+ YangStmtMapping.USES);
+ private static final ImmutableSet<YangStmtMapping> NOCOPY_FROM_GROUPING_SET = ImmutableSet.of(
+ YangStmtMapping.DESCRIPTION,
+ YangStmtMapping.REFERENCE,
+ YangStmtMapping.STATUS);
+
+ private void copySubstatement(final Mutable<?, ?, ?> substatement, final Collection<Mutable<?, ?, ?>> buffer) {
+ final StatementDefinition def = substatement.getPublicDefinition();
+
+ // FIXME: YANGTOOLS-652: formerly known as "isReusedByUses"
+ if (REUSED_DEF_SET.contains(def)) {
+ LOG.debug("Reusing substatement {} for {}", substatement, this);
+ buffer.add(substatement);
+ return;
+ }
+ // FIXME: YANGTOOLS-652: formerly known as "needToCopyByUses" (note inverted check, though)
+ if (NOCOPY_FROM_GROUPING_SET.contains(def)) {
+ // This is to say: if parent of source context is a grouping, ignore this statement.
+ if (YangStmtMapping.GROUPING.equals(substatement.coerceParentContext().getPublicDefinition())) {
+ LOG.debug("Skipping grouping statement {}", substatement);
+ return;
+ }
+ }
+
+ // FIXME: YANGTOOLS-694: we are forcing a copy here, hence even statements not affected by parent, copyType
+ // or targetModule (and don't forget its substatements!). This really should be a callout
+ // to StatementSupport. Note if that callout is allowed to return an Optional, it can
+ // take care at least of the 'grouping from uses' case above.
+ final Mutable<?, ?, ?> copy = childCopyOf(substatement, childCopyType, targetModule);
+ LOG.debug("Copying substatement {} for {} as {}", substatement, this, copy);
+ buffer.add(copy);
+ }
+
+ // Statement copy mess ends here
+
+ /*
+ * KEEP THINGS ORGANIZED!
+ *
+ * below methods exist in the same form in SubstatementContext. If any adjustment is made here, make sure it is
+ * properly updated there.
+ */
+ @Override
+ public Optional<SchemaPath> getSchemaPath() {
+ return substatementGetSchemaPath();
+ }
+
+ @Override
+ public A getStatementArgument() {
+ return argument;
+ }
+
+ @Override
+ public StatementContextBase<?, ?, ?> getParentContext() {
+ return parent;
+ }
+
+ @Override
+ public StorageNodeType getStorageNodeType() {
+ return StorageNodeType.STATEMENT_LOCAL;
+ }
+
+ @Override
+ public NamespaceStorageNode getParentNamespaceStorage() {
+ return parent;
+ }
+
+ @Override
+ public RootStatementContext<?, ?, ?> getRoot() {
+ return parent.getRoot();
+ }
+
+ @Override
+ public boolean isConfiguration() {
+ return isConfiguration(parent);
+ }
+
+ @Override
+ protected boolean isIgnoringIfFeatures() {
+ return isIgnoringIfFeatures(parent);
+ }
+
+ @Override
+ protected boolean isIgnoringConfig() {
+ return isIgnoringConfig(parent);
+ }
+
+ @Override
+ protected boolean isParentSupportedByFeatures() {
+ return parent.isSupportedByFeatures();
+ }
+}
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.YangVersion;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
public static final YangVersion DEFAULT_VERSION = YangVersion.VERSION_1;
- private final SourceSpecificContext sourceContext;
+ private final @NonNull SourceSpecificContext sourceContext;
private final A argument;
private YangVersion rootVersion;
return sourceContext;
}
- @Override
- public Registry getBehaviourRegistry() {
- return sourceContext;
- }
-
@Override
public StorageNodeType getStorageNodeType() {
return StorageNodeType.ROOT_STATEMENT_LOCAL;
return true;
}
- @Override
- public boolean isEnabledSemanticVersioning() {
- return sourceContext.isEnabledSemanticVersioning();
- }
-
@Override
public <K, V, N extends IdentifierNamespace<K, V>> V putToLocalStorage(final Class<N> type, final K key,
final V value) {
return null;
}
- @Override
- public YangVersion getRootVersion() {
- return rootVersion == null ? DEFAULT_VERSION : rootVersion;
- }
-
- @Override
- public void setRootVersion(final YangVersion version) {
- checkArgument(sourceContext.getSupportedVersions().contains(version),
- "Unsupported yang version %s in %s", version, getStatementSourceReference());
- checkState(this.rootVersion == null, "Version of root %s has been already set to %s", argument,
- this.rootVersion);
- this.rootVersion = requireNonNull(version);
- }
-
- @Override
- public void addMutableStmtToSeal(final MutableStatement mutableStatement) {
- sourceContext.addMutableStmtToSeal(mutableStatement);
- }
-
- @Override
- public void addRequiredSource(final SourceIdentifier dependency) {
- checkState(sourceContext.getInProgressPhase() == ModelProcessingPhase.SOURCE_PRE_LINKAGE,
- "Add required module is allowed only in ModelProcessingPhase.SOURCE_PRE_LINKAGE phase");
- if (requiredSources.isEmpty()) {
- requiredSources = new HashSet<>();
- }
- requiredSources.add(dependency);
- }
-
/**
* Return the set of required sources.
*
return ImmutableSet.copyOf(requiredSources);
}
- @Override
- public void setRootIdentifier(final SourceIdentifier identifier) {
- this.rootIdentifier = requireNonNull(identifier);
- }
-
SourceIdentifier getRootIdentifier() {
return rootIdentifier;
}
return true;
}
+ void setRootIdentifierImpl(final SourceIdentifier identifier) {
+ this.rootIdentifier = requireNonNull(identifier);
+ }
+
+ @NonNull Registry getBehaviourRegistryImpl() {
+ return sourceContext;
+ }
+
+ boolean isEnabledSemanticVersioningImpl() {
+ return sourceContext.isEnabledSemanticVersioning();
+ }
+
+ @NonNull YangVersion getRootVersionImpl() {
+ return rootVersion == null ? DEFAULT_VERSION : rootVersion;
+ }
+
+ void setRootVersionImpl(final YangVersion version) {
+ checkArgument(sourceContext.getSupportedVersions().contains(version),
+ "Unsupported yang version %s in %s", version, getStatementSourceReference());
+ checkState(this.rootVersion == null, "Version of root %s has been already set to %s", argument,
+ this.rootVersion);
+ this.rootVersion = requireNonNull(version);
+ }
+
+ void addMutableStmtToSealImpl(final MutableStatement mutableStatement) {
+ sourceContext.addMutableStmtToSeal(mutableStatement);
+ }
+
+ void addRequiredSourceImpl(final SourceIdentifier dependency) {
+ checkState(sourceContext.getInProgressPhase() == ModelProcessingPhase.SOURCE_PRE_LINKAGE,
+ "Add required module is allowed only in ModelProcessingPhase.SOURCE_PRE_LINKAGE phase");
+ if (requiredSources.isEmpty()) {
+ requiredSources = new HashSet<>();
+ }
+ requiredSources.add(dependency);
+ }
+
@Override
StatementContextBase<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
throw new UnsupportedOperationException("Root statement cannot be reparented to" + newParent);
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Verify.verify;
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.util.ArrayList;
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.model.api.YangStmtMapping;
+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.meta.StatementSource;
+import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
+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.CopyHistory;
import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
import org.opendaylight.yangtools.yang.parser.spi.meta.ImplicitParentAwareStatementSupport;
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;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace;
import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace.SupportedFeatures;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.KeyedValueAddedListener;
private static final int SET_IGNORE_CONFIG = HAVE_IGNORE_CONFIG | IS_IGNORE_CONFIG | SET_CONFIGURATION;
private static final int SET_IGNORE_IF_FEATURE = HAVE_IGNORE_IF_FEATURE | IS_IGNORE_IF_FEATURE;
- private final @NonNull StatementDefinitionContext<A, D, E> definition;
- private final @NonNull StatementSourceReference statementDeclSource;
- private final StmtContext<?, ?, ?> originalCtx;
- private final StmtContext<?, ?, ?> prevCopyCtx;
private final CopyHistory copyHistory;
- private final String rawArgument;
+ // Note: this field can strictly be derived in InferredStatementContext, but it forms the basis of many of our
+ // operations, hence we want to keep it close by.
+ private final @NonNull StatementDefinitionContext<A, D, E> definition;
private Multimap<ModelProcessingPhase, OnPhaseFinished> phaseListeners = ImmutableMultimap.of();
private Multimap<ModelProcessingPhase, ContextMutation> phaseMutation = ImmutableMultimap.of();
// hence improve memory layout.
private byte flags;
- StatementContextBase(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
- final String rawArgument) {
- this.definition = requireNonNull(def);
- this.statementDeclSource = requireNonNull(ref);
- this.rawArgument = def.internArgument(rawArgument);
- this.copyHistory = CopyHistory.original();
- this.originalCtx = null;
- this.prevCopyCtx = null;
- }
+ // 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.
+ private volatile SchemaPath schemaPath;
- StatementContextBase(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
- final String rawArgument, final CopyType copyType) {
- this.definition = requireNonNull(def);
- this.statementDeclSource = requireNonNull(ref);
- this.rawArgument = rawArgument;
- this.copyHistory = CopyHistory.of(copyType, CopyHistory.original());
- this.originalCtx = null;
- this.prevCopyCtx = null;
+ StatementContextBase(final StatementContextBase<A, D, E> original) {
+ this.copyHistory = original.copyHistory;
+ this.definition = original.definition;
}
- StatementContextBase(final StatementContextBase<A, D, E> original, final CopyType copyType) {
- this.definition = original.definition;
- this.statementDeclSource = original.statementDeclSource;
- this.rawArgument = original.rawArgument;
- this.copyHistory = CopyHistory.of(copyType, original.getCopyHistory());
- this.originalCtx = original.getOriginalCtx().orElse(original);
- this.prevCopyCtx = original;
+ StatementContextBase(final StatementDefinitionContext<A, D, E> def) {
+ this.definition = requireNonNull(def);
+ this.copyHistory = CopyHistory.original();
}
- StatementContextBase(final StatementContextBase<A, D, E> original) {
- this.definition = original.definition;
- this.statementDeclSource = original.statementDeclSource;
- this.rawArgument = original.rawArgument;
- this.copyHistory = original.getCopyHistory();
- this.originalCtx = original.getOriginalCtx().orElse(original);
- this.prevCopyCtx = original;
- this.effective = original.effective;
+ StatementContextBase(final StatementDefinitionContext<A, D, E> def, final CopyHistory copyHistory) {
+ this.definition = requireNonNull(def);
+ this.copyHistory = requireNonNull(copyHistory);
}
@Override
return copyHistory;
}
- @Override
- public Optional<StmtContext<?, ?, ?>> getOriginalCtx() {
- return Optional.ofNullable(originalCtx);
- }
-
- @Override
- public Optional<? extends StmtContext<?, ?, ?>> getPreviousCopyCtx() {
- return Optional.ofNullable(prevCopyCtx);
- }
-
@Override
public ModelProcessingPhase getCompletedPhase() {
return completedPhase;
public abstract RootStatementContext<?, ?, ?> getRoot();
@Override
- public StatementSource getStatementSource() {
- return statementDeclSource.getStatementSource();
+ public final @NonNull Registry getBehaviourRegistry() {
+ return getRoot().getBehaviourRegistryImpl();
}
@Override
- public StatementSourceReference getStatementSourceReference() {
- return statementDeclSource;
+ public final YangVersion getRootVersion() {
+ return getRoot().getRootVersionImpl();
}
@Override
- public final String rawStatementArgument() {
- return rawArgument;
+ public final void setRootVersion(final YangVersion version) {
+ getRoot().setRootVersionImpl(version);
}
@Override
- public abstract Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements();
+ public final void addMutableStmtToSeal(final MutableStatement mutableStatement) {
+ getRoot().addMutableStmtToSealImpl(mutableStatement);
+ }
@Override
- public Collection<? extends StmtContext<?, ?, ?>> effectiveSubstatements() {
- return mutableEffectiveSubstatements();
+ public final void addRequiredSource(final SourceIdentifier dependency) {
+ getRoot().addRequiredSourceImpl(dependency);
}
+ @Override
+ public final void setRootIdentifier(final SourceIdentifier identifier) {
+ getRoot().setRootIdentifierImpl(identifier);
+ }
+
+ @Override
+ public final boolean isEnabledSemanticVersioning() {
+ return getRoot().isEnabledSemanticVersioningImpl();
+ }
+
+ @Override
+ public StatementSource getStatementSource() {
+ return getStatementSourceReference().getStatementSource();
+ }
+
+ @Override
+ public abstract Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements();
+
@Override
public Collection<? extends Mutable<?, ?, ?>> mutableEffectiveSubstatements() {
if (effective instanceof ImmutableCollection) {
checkArgument(completedPhase == ModelProcessingPhase.FULL_DECLARATION
|| completedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
if (declaredInstance == null) {
- declaredInstance = definition().getFactory().createDeclared(this);
+ declaredInstance = definition.getFactory().createDeclared(this);
}
return declaredInstance;
}
@Override
public E buildEffective() {
if (effectiveInstance == null) {
- effectiveInstance = definition().getFactory().createEffective(this);
+ effectiveInstance = definition.getFactory().createEffective(this);
}
return effectiveInstance;
}
* Ends declared section of current node.
*/
void endDeclared(final ModelProcessingPhase phase) {
- definition().onDeclarationFinished(this, phase);
+ definition.onDeclarationFinished(this, phase);
}
/**
@Override
protected void checkLocalNamespaceAllowed(final Class<? extends IdentifierNamespace<?, ?>> type) {
- definition().checkNamespaceAllowed(type);
+ definition.checkNamespaceAllowed(type);
}
@Override
@Override
public StatementDefinition getPublicDefinition() {
- return definition().getPublicView();
+ return definition.getPublicView();
}
@Override
checkState(stmt.getCompletedPhase() == ModelProcessingPhase.EFFECTIVE_MODEL,
"Attempted to copy statement %s which has completed phase %s", stmt, stmt.getCompletedPhase());
- checkArgument(stmt instanceof SubstatementContext, "Unsupported statement %s", stmt);
+ checkArgument(stmt instanceof StatementContextBase, "Unsupported statement %s", stmt);
+ return childCopyOf((StatementContextBase<X, Y, Z>)stmt, type, targetModule);
+ }
- final SubstatementContext<X, Y, Z> original = (SubstatementContext<X, Y, Z>)stmt;
+ private <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>> Mutable<X, Y, Z> childCopyOf(
+ final StatementContextBase<X, Y, Z> original, final CopyType type, final QNameModule targetModule) {
final Optional<StatementSupport<?, ?, ?>> implicitParent = definition.getImplicitParentFor(
original.getPublicDefinition());
- final SubstatementContext<X, Y, Z> result;
- final SubstatementContext<X, Y, Z> copy;
+ final StatementContextBase<X, Y, Z> result;
+ final InferredStatementContext<X, Y, Z> copy;
if (implicitParent.isPresent()) {
final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(implicitParent.get());
childCopyType = type;
}
- copy = new SubstatementContext<>(original, result, childCopyType, targetModule);
+ copy = new InferredStatementContext<>(result, original, childCopyType, type, targetModule);
result.addEffectiveSubstatement(copy);
} else {
- result = copy = new SubstatementContext<>(original, this, type, targetModule);
+ result = copy = new InferredStatementContext<>(this, original, type, type, targetModule);
}
- original.definition().onStatementAdded(copy);
- original.copyTo(copy, type, targetModule);
+ original.definition.onStatementAdded(copy);
return result;
}
if (fl != 0) {
return fl == SET_IGNORE_CONFIG;
}
- if (definition().isIgnoringConfig() || parent.isIgnoringConfig()) {
+ if (definition.isIgnoringConfig() || parent.isIgnoringConfig()) {
flags |= SET_IGNORE_CONFIG;
return true;
}
if (fl != 0) {
return fl == SET_IGNORE_IF_FEATURE;
}
- if (definition().isIgnoringIfFeatures() || parent.isIgnoringIfFeatures()) {
+ if (definition.isIgnoringIfFeatures() || parent.isIgnoringIfFeatures()) {
flags |= SET_IGNORE_IF_FEATURE;
return true;
}
return false;
}
- final void copyTo(final StatementContextBase<?, ?, ?> target, final CopyType typeOfCopy,
- @Nullable final QNameModule targetModule) {
- final Collection<? extends StatementContextBase<?, ?, ?>> declared = mutableDeclaredSubstatements();
- final Collection<Mutable<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size());
-
- for (final Mutable<?, ?, ?> stmtContext : declared) {
- if (stmtContext.isSupportedByFeatures()) {
- copySubstatement(stmtContext, target, typeOfCopy, targetModule, buffer);
+ // Exists only to support SubstatementContext/InferredStatementContext
+ final @NonNull Optional<SchemaPath> substatementGetSchemaPath() {
+ SchemaPath local = schemaPath;
+ if (local == null) {
+ synchronized (this) {
+ local = schemaPath;
+ if (local == null) {
+ local = createSchemaPath(coerceParentContext());
+ schemaPath = local;
+ }
}
}
- for (final Mutable<?, ?, ?> stmtContext : effective) {
- copySubstatement(stmtContext, target, typeOfCopy, targetModule, buffer);
- }
- target.addEffectiveSubstatements(buffer);
+ return Optional.ofNullable(local);
}
- private void copySubstatement(final Mutable<?, ?, ?> stmtContext, final Mutable<?, ?, ?> target,
- final CopyType typeOfCopy, final QNameModule newQNameModule, final Collection<Mutable<?, ?, ?>> buffer) {
- if (needToCopyByUses(stmtContext)) {
- final Mutable<?, ?, ?> copy = target.childCopyOf(stmtContext, typeOfCopy, newQNameModule);
- LOG.debug("Copying substatement {} for {} as {}", stmtContext, this, copy);
- buffer.add(copy);
- } else if (isReusedByUses(stmtContext)) {
- LOG.debug("Reusing substatement {} for {}", stmtContext, this);
- buffer.add(stmtContext);
- } else {
- LOG.debug("Skipping statement {}", stmtContext);
- }
- }
+ private SchemaPath createSchemaPath(final Mutable<?, ?, ?> parent) {
+ final Optional<SchemaPath> maybeParentPath = parent.getSchemaPath();
+ verify(maybeParentPath.isPresent(), "Parent %s does not have a SchemaPath", parent);
+ final SchemaPath parentPath = maybeParentPath.get();
- // FIXME: revise this, as it seems to be wrong
- private static final ImmutableSet<YangStmtMapping> NOCOPY_FROM_GROUPING_SET = ImmutableSet.of(
- YangStmtMapping.DESCRIPTION,
- YangStmtMapping.REFERENCE,
- YangStmtMapping.STATUS);
- private static final ImmutableSet<YangStmtMapping> REUSED_DEF_SET = ImmutableSet.of(
- YangStmtMapping.TYPE,
- YangStmtMapping.TYPEDEF,
- YangStmtMapping.USES);
+ if (StmtContextUtils.isUnknownStatement(this)) {
+ return parentPath.createChild(getPublicDefinition().getStatementName());
+ }
+ final Object argument = getStatementArgument();
+ if (argument instanceof QName) {
+ final QName qname = (QName) argument;
+ if (StmtContextUtils.producesDeclared(this, UsesStatement.class)) {
+ return maybeParentPath.orElse(null);
+ }
- private static boolean needToCopyByUses(final StmtContext<?, ?, ?> stmtContext) {
- final StatementDefinition def = stmtContext.getPublicDefinition();
- if (REUSED_DEF_SET.contains(def)) {
- LOG.debug("Will reuse {} statement {}", def, stmtContext);
- return false;
+ return parentPath.createChild(qname);
}
- if (NOCOPY_FROM_GROUPING_SET.contains(def)) {
- return !YangStmtMapping.GROUPING.equals(stmtContext.coerceParentContext().getPublicDefinition());
+ if (argument instanceof String) {
+ // FIXME: This may yield illegal argument exceptions
+ final Optional<StmtContext<?, ?, ?>> originalCtx = getOriginalCtx();
+ final QName qname = StmtContextUtils.qnameFromArgument(originalCtx.orElse(this), (String) argument);
+ return parentPath.createChild(qname);
}
+ if (argument instanceof SchemaNodeIdentifier
+ && (StmtContextUtils.producesDeclared(this, AugmentStatement.class)
+ || StmtContextUtils.producesDeclared(this, RefineStatement.class)
+ || StmtContextUtils.producesDeclared(this, DeviationStatement.class))) {
- LOG.debug("Will copy {} statement {}", def, stmtContext);
- return true;
- }
+ return parentPath.createChild(((SchemaNodeIdentifier) argument).getPathFromRoot());
+ }
- private static boolean isReusedByUses(final StmtContext<?, ?, ?> stmtContext) {
- return REUSED_DEF_SET.contains(stmtContext.getPublicDefinition());
+ // FIXME: this does not look right
+ return maybeParentPath.orElse(null);
}
@Override
}
protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
- return toStringHelper.add("definition", definition).add("rawArgument", rawArgument);
+ return toStringHelper.add("definition", definition).add("rawArgument", rawStatementArgument());
}
}
import static java.util.Objects.requireNonNull;
-import com.google.common.base.Verify;
import java.util.Optional;
-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.stmt.AugmentStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
-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.CopyType;
-import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends
private final StatementContextBase<?, ?, ?> parent;
private final A argument;
- private volatile SchemaPath schemaPath;
+ private SubstatementContext(final SubstatementContext<A, D, E> original,
+ final StatementContextBase<?, ?, ?> parent) {
+ super(original);
+ this.parent = requireNonNull(parent, "Parent must not be null");
+ this.argument = original.argument;
+ }
SubstatementContext(final StatementContextBase<?, ?, ?> parent, final StatementDefinitionContext<A, D, E> def,
final StatementSourceReference ref, final String rawArgument) {
this.argument = def.parseArgumentValue(this, rawStatementArgument());
}
+ // FIXME: YANGTOOLS-784: this constructor is only called in contexts where a different implementation
+ // would be more appropriate
SubstatementContext(final StatementContextBase<?, ?, ?> parent, final StatementDefinitionContext<A, D, E> def,
- final StatementSourceReference ref, final String rawArgument, final A argument, final CopyType copyType) {
+ final StatementSourceReference ref, final String rawArgument, final A argument, final CopyType copyType) {
super(def, ref, rawArgument, copyType);
this.parent = requireNonNull(parent, "Parent must not be null");
this.argument = argument;
}
- SubstatementContext(final StatementContextBase<A, D, E> original, final StatementContextBase<?, ?, ?> parent,
- final CopyType copyType, final QNameModule targetModule) {
- super(original, copyType);
- this.parent = requireNonNull(parent, "Parent must not be null");
- this.argument = targetModule == null ? original.getStatementArgument()
- : original.definition().adaptArgumentValue(original, targetModule);
+ @Override
+ SubstatementContext<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
+ return new SubstatementContext<>(this, newParent);
}
- private SubstatementContext(final SubstatementContext<A, D, E> original,
- final StatementContextBase<?, ?, ?> parent) {
- super(original);
- this.parent = requireNonNull(parent, "Parent must not be null");
- this.argument = original.argument;
+ /*
+ * KEEP THINGS ORGANIZED!
+ *
+ * below methods exist in the same form in InferredStatementContext. If any adjustment is made here, make sure it is
+ * properly updated there.
+ */
+ @Override
+ public Optional<SchemaPath> getSchemaPath() {
+ return substatementGetSchemaPath();
+ }
+
+ @Override
+ public A getStatementArgument() {
+ return argument;
}
@Override
return parent;
}
- @Override
- public Registry getBehaviourRegistry() {
- return parent.getBehaviourRegistry();
- }
-
@Override
public RootStatementContext<?, ?, ?> getRoot() {
return parent.getRoot();
}
- @Override
- public A getStatementArgument() {
- return argument;
- }
-
- private SchemaPath createSchemaPath() {
- final Optional<SchemaPath> maybeParentPath = parent.getSchemaPath();
- Verify.verify(maybeParentPath.isPresent(), "Parent %s does not have a SchemaPath", parent);
- final SchemaPath parentPath = maybeParentPath.get();
-
- if (StmtContextUtils.isUnknownStatement(this)) {
- return parentPath.createChild(getPublicDefinition().getStatementName());
- }
- if (argument instanceof QName) {
- final QName qname = (QName) argument;
- if (StmtContextUtils.producesDeclared(this, UsesStatement.class)) {
- return maybeParentPath.orElse(null);
- }
-
- return parentPath.createChild(qname);
- }
- if (argument instanceof String) {
- // FIXME: This may yield illegal argument exceptions
- final Optional<StmtContext<?, ?, ?>> originalCtx = getOriginalCtx();
- final QName qname = StmtContextUtils.qnameFromArgument(originalCtx.orElse(this), (String) argument);
- return parentPath.createChild(qname);
- }
- if (argument instanceof SchemaNodeIdentifier
- && (StmtContextUtils.producesDeclared(this, AugmentStatement.class)
- || StmtContextUtils.producesDeclared(this, RefineStatement.class)
- || StmtContextUtils.producesDeclared(this, DeviationStatement.class))) {
-
- return parentPath.createChild(((SchemaNodeIdentifier) argument).getPathFromRoot());
- }
-
- // FIXME: this does not look right
- return maybeParentPath.orElse(null);
- }
-
- @Override
- public Optional<SchemaPath> getSchemaPath() {
- SchemaPath local = schemaPath;
- if (local == null) {
- synchronized (this) {
- local = schemaPath;
- if (local == null) {
- local = createSchemaPath();
- schemaPath = local;
- }
- }
- }
-
- return Optional.ofNullable(local);
- }
-
@Override
public boolean isConfiguration() {
return isConfiguration(parent);
}
- @Override
- public boolean isEnabledSemanticVersioning() {
- return parent.isEnabledSemanticVersioning();
- }
-
- @Override
- public YangVersion getRootVersion() {
- return getRoot().getRootVersion();
- }
-
- @Override
- public void setRootVersion(final YangVersion version) {
- getRoot().setRootVersion(version);
- }
-
- @Override
- public void addMutableStmtToSeal(final MutableStatement mutableStatement) {
- getRoot().addMutableStmtToSeal(mutableStatement);
- }
-
- @Override
- public void addRequiredSource(final SourceIdentifier dependency) {
- getRoot().addRequiredSource(dependency);
- }
-
- @Override
- public void setRootIdentifier(final SourceIdentifier identifier) {
- getRoot().setRootIdentifier(identifier);
- }
-
@Override
protected boolean isIgnoringIfFeatures() {
return isIgnoringIfFeatures(parent);
protected boolean isParentSupportedByFeatures() {
return parent.isSupportedByFeatures();
}
-
- @Override
- SubstatementContext<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
- return new SubstatementContext<>(this, newParent);
- }
}
}
}
+ // FIXME: YANGTOOLS-652: these maps look very much like those in InferredStatementContext
private static final ImmutableSet<YangStmtMapping> TOP_REUSED_DEF_SET = ImmutableSet.of(
YangStmtMapping.TYPE,
YangStmtMapping.TYPEDEF);
return childCopyOf(stmt, type, null);
}
+ @Override
+ default Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
+ return mutableDeclaredSubstatements();
+ }
+
@NonNull Collection<? extends Mutable<?, ?, ?>> mutableDeclaredSubstatements();
+ @Override
+ default Collection<? extends StmtContext<?, ?, ?>> effectiveSubstatements() {
+ return mutableEffectiveSubstatements();
+ }
+
@NonNull Collection<? extends Mutable<?, ?, ?>> mutableEffectiveSubstatements();
/**