import org.opendaylight.yangtools.yang.common.QNameModule;
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.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.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.NamespaceKeyCriterion;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
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.StatementSupport.CopyPolicy;
}
@Override
- public CopyHistory history() {
+ public final CopyHistory history() {
return copyHistory;
}
@Override
- public ModelProcessingPhase getCompletedPhase() {
+ public final ModelProcessingPhase getCompletedPhase() {
return completedPhase;
}
}
@Override
- public final <K, V, T extends K, U extends V, N extends IdentifierNamespace<K, V>> void addToNs(
+ public final <K, V, T extends K, U extends V, N extends ParserNamespace<K, V>> void addToNs(
final Class<@NonNull N> type, final T key, final U value) {
addToNamespace(type, key, value);
}
static final Collection<? extends Mutable<?, ?, ?>> mutableEffectiveSubstatements(
- final List<StatementContextBase<?, ?, ?>> effective) {
+ final List<ReactorStmtCtx<?, ?, ?>> effective) {
return effective instanceof ImmutableCollection ? effective : Collections.unmodifiableCollection(effective);
}
- private static List<StatementContextBase<?, ?, ?>> shrinkEffective(
- final List<StatementContextBase<?, ?, ?>> effective) {
+ private static List<ReactorStmtCtx<?, ?, ?>> shrinkEffective(final List<ReactorStmtCtx<?, ?, ?>> effective) {
return effective.isEmpty() ? ImmutableList.of() : effective;
}
public abstract void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef);
- static final List<StatementContextBase<?, ?, ?>> removeStatementFromEffectiveSubstatements(
- final List<StatementContextBase<?, ?, ?>> effective, final StatementDefinition statementDef) {
+ static final List<ReactorStmtCtx<?, ?, ?>> removeStatementFromEffectiveSubstatements(
+ final List<ReactorStmtCtx<?, ?, ?>> effective, final StatementDefinition statementDef) {
if (effective.isEmpty()) {
return effective;
}
public abstract void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef,
String statementArg);
- static final List<StatementContextBase<?, ?, ?>> removeStatementFromEffectiveSubstatements(
- final List<StatementContextBase<?, ?, ?>> effective, final StatementDefinition statementDef,
+ static final List<ReactorStmtCtx<?, ?, ?>> removeStatementFromEffectiveSubstatements(
+ final List<ReactorStmtCtx<?, ?, ?>> effective, final StatementDefinition statementDef,
final String statementArg) {
if (statementArg == null) {
return removeStatementFromEffectiveSubstatements(effective, statementDef);
return effective;
}
- final Iterator<StatementContextBase<?, ?, ?>> iterator = effective.iterator();
+ final Iterator<ReactorStmtCtx<?, ?, ?>> iterator = effective.iterator();
while (iterator.hasNext()) {
final Mutable<?, ?, ?> next = iterator.next();
if (statementDef.equals(next.publicDefinition()) && statementArg.equals(next.rawArgument())) {
*/
public abstract void addEffectiveSubstatement(Mutable<?, ?, ?> substatement);
- final List<StatementContextBase<?, ?, ?>> addEffectiveSubstatement(
- final List<StatementContextBase<?, ?, ?>> effective, final Mutable<?, ?, ?> substatement) {
+ final List<ReactorStmtCtx<?, ?, ?>> addEffectiveSubstatement(final List<ReactorStmtCtx<?, ?, ?>> effective,
+ final Mutable<?, ?, ?> substatement) {
verifyStatement(substatement);
- final List<StatementContextBase<?, ?, ?>> resized = beforeAddEffectiveStatement(effective, 1);
- final StatementContextBase<?, ?, ?> stmt = (StatementContextBase<?, ?, ?>) substatement;
+ final List<ReactorStmtCtx<?, ?, ?>> resized = beforeAddEffectiveStatement(effective, 1);
+ final ReactorStmtCtx<?, ?, ?> stmt = (ReactorStmtCtx<?, ?, ?>) substatement;
final ModelProcessingPhase phase = completedPhase;
if (phase != null) {
ensureCompletedPhase(stmt, phase);
abstract void addEffectiveSubstatementsImpl(Collection<? extends Mutable<?, ?, ?>> statements);
- final List<StatementContextBase<?, ?, ?>> addEffectiveSubstatementsImpl(
- final List<StatementContextBase<?, ?, ?>> effective,
+ final List<ReactorStmtCtx<?, ?, ?>> addEffectiveSubstatementsImpl(final List<ReactorStmtCtx<?, ?, ?>> effective,
final Collection<? extends Mutable<?, ?, ?>> statements) {
- final List<StatementContextBase<?, ?, ?>> resized = beforeAddEffectiveStatement(effective, statements.size());
+ final List<ReactorStmtCtx<?, ?, ?>> resized = beforeAddEffectiveStatement(effective, statements.size());
final Collection<? extends StatementContextBase<?, ?, ?>> casted =
(Collection<? extends StatementContextBase<?, ?, ?>>) statements;
final ModelProcessingPhase phase = completedPhase;
return resized;
}
- abstract Iterable<StatementContextBase<?, ?, ?>> effectiveChildrenToComplete();
+ abstract Iterable<ReactorStmtCtx<?, ?, ?>> effectiveChildrenToComplete();
// exposed for InferredStatementContext only
final void ensureCompletedPhase(final Mutable<?, ?, ?> stmt) {
verifyStatement(stmt);
final ModelProcessingPhase phase = completedPhase;
if (phase != null) {
- ensureCompletedPhase((StatementContextBase<?, ?, ?>) stmt, phase);
+ ensureCompletedPhase((ReactorStmtCtx<?, ?, ?>) stmt, phase);
}
}
// Make sure target statement has transitioned at least to specified phase. This method is just before we take
// allow a statement to become our substatement. This is needed to ensure that every statement tree does not contain
// any statements which did not complete the same phase as the root statement.
- private static void ensureCompletedPhase(final StatementContextBase<?, ?, ?> stmt,
- final ModelProcessingPhase phase) {
+ private static void ensureCompletedPhase(final ReactorStmtCtx<?, ?, ?> stmt, final ModelProcessingPhase phase) {
verify(stmt.tryToCompletePhase(phase), "Statement %s cannot complete phase %s", stmt, phase);
}
private static void verifyStatement(final Mutable<?, ?, ?> stmt) {
- verify(stmt instanceof StatementContextBase, "Unexpected statement %s", stmt);
+ verify(stmt instanceof ReactorStmtCtx, "Unexpected statement %s", stmt);
}
- private List<StatementContextBase<?, ?, ?>> beforeAddEffectiveStatement(
- final List<StatementContextBase<?, ?, ?>> effective, final int toAdd) {
+ private List<ReactorStmtCtx<?, ?, ?>> beforeAddEffectiveStatement(final List<ReactorStmtCtx<?, ?, ?>> effective,
+ final int toAdd) {
// We cannot allow statement to be further mutated
verify(completedPhase != ModelProcessingPhase.EFFECTIVE_MODEL, "Cannot modify finished statement at %s",
sourceReference());
return beforeAddEffectiveStatementUnsafe(effective, toAdd);
}
- final List<StatementContextBase<?, ?, ?>> beforeAddEffectiveStatementUnsafe(
- final List<StatementContextBase<?, ?, ?>> effective, final int toAdd) {
+ final List<ReactorStmtCtx<?, ?, ?>> beforeAddEffectiveStatementUnsafe(final List<ReactorStmtCtx<?, ?, ?>> effective,
+ final int toAdd) {
final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase();
checkState(inProgressPhase == ModelProcessingPhase.FULL_DECLARATION
|| inProgressPhase == ModelProcessingPhase.EFFECTIVE_MODEL,
return effective.isEmpty() ? new ArrayList<>(toAdd) : effective;
}
- // Exposed for ReplicaStatementContext
+
@Override
- E createEffective() {
- return definition.getFactory().createEffective(this, streamDeclared(), streamEffective());
+ final E createEffective() {
+ final E result = definition.getFactory().createEffective(this, streamDeclared(), streamEffective());
+ if (result instanceof MutableStatement) {
+ getRoot().addMutableStmtToSeal((MutableStatement) result);
+ }
+ return result;
}
abstract Stream<? extends StmtContext<?, ?, ?>> streamDeclared();
abstract Stream<? extends StmtContext<?, ?, ?>> streamEffective();
- /**
- * Try to execute current {@link ModelProcessingPhase} of source parsing. If the phase has already been executed,
- * this method does nothing.
- *
- * @param phase to be executed (completed)
- * @return true if phase was successfully completed
- * @throws SourceException when an error occurred in source parsing
- */
- final boolean tryToCompletePhase(final ModelProcessingPhase phase) {
- return phase.isCompletedBy(completedPhase) || doTryToCompletePhase(phase);
- }
-
- private boolean doTryToCompletePhase(final ModelProcessingPhase phase) {
+ @Override
+ final boolean doTryToCompletePhase(final ModelProcessingPhase phase) {
final boolean finished = phaseMutation.isEmpty() ? true : runMutations(phase);
if (completeChildren(phase) && finished) {
onPhaseCompleted(phase);
for (final StatementContextBase<?, ?, ?> child : mutableDeclaredSubstatements()) {
finished &= child.tryToCompletePhase(phase);
}
- for (final StatementContextBase<?, ?, ?> child : effectiveChildrenToComplete()) {
+ for (final ReactorStmtCtx<?, ?, ?> child : effectiveChildrenToComplete()) {
finished &= child.tryToCompletePhase(phase);
}
return finished;
return definition;
}
- final <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceItemAddedAction(final Class<N> type, final K key,
+ final <K, V, N extends ParserNamespace<K, V>> void onNamespaceItemAddedAction(final Class<N> type, final K key,
final OnNamespaceItemAdded listener) {
final Object potential = getFromNamespace(type, key);
if (potential != null) {
});
}
- final <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceItemAddedAction(final Class<N> type,
+ final <K, V, N extends ParserNamespace<K, V>> void onNamespaceItemAddedAction(final Class<N> type,
final ModelProcessingPhase phase, final NamespaceKeyCriterion<K> criterion,
final OnNamespaceItemAdded listener) {
final Optional<Entry<K, V>> existing = getFromNamespace(type, criterion);
});
}
- final <K, V, N extends IdentifierNamespace<K, V>> void selectMatch(final Class<N> type,
+ final <K, V, N extends ParserNamespace<K, V>> void selectMatch(final Class<N> type,
final NamespaceKeyCriterion<K> criterion, final OnNamespaceItemAdded listener) {
final Optional<Entry<K, V>> optMatch = getFromNamespace(type, criterion);
checkState(optMatch.isPresent(), "Failed to find a match for criterion %s in namespace %s node %s", criterion,
listener.namespaceItemAdded(StatementContextBase.this, type, match.getKey(), match.getValue());
}
- final <K, V, N extends IdentifierNamespace<K, V>> void waitForPhase(final Object value, final Class<N> type,
+ final <K, V, N extends ParserNamespace<K, V>> void waitForPhase(final Object value, final Class<N> type,
final ModelProcessingPhase phase, final NamespaceKeyCriterion<K> criterion,
final OnNamespaceItemAdded listener) {
((StatementContextBase<?, ? ,?>) value).addPhaseCompletedListener(phase,
});
}
- private <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> getBehaviour(
+ private <K, V, N extends ParserNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> getBehaviour(
final Class<N> type) {
final NamespaceBehaviour<K, V, N> behaviour = getBehaviourRegistry().getNamespaceBehaviour(type);
checkArgument(behaviour instanceof NamespaceBehaviourWithListeners, "Namespace %s does not support listeners",
checkEffectiveModelCompleted(this);
final StatementSupport<A, D, E> support = definition.support();
- final CopyPolicy policy = support.applyCopyPolicy(this, parent, type, targetModule);
+ final CopyPolicy policy = support.copyPolicy();
switch (policy) {
case CONTEXT_INDEPENDENT:
- if (hasEmptySubstatements()) {
- // This statement is context-independent and has no substatements -- hence it can be freely shared.
+ if (substatementsContextIndependent()) {
return Optional.of(replicaAsChildOf(parent));
}
- // FIXME: YANGTOOLS-694: filter out all context-independent substatements, eliminate fall-through
+
// fall through
case DECLARED_COPY:
- // FIXME: YANGTOOLS-694: this is still to eager, we really want to copy as a lazily-instantiated
- // context, so that we can support building an effective statement without copying
- // anything -- we will typically end up not being inferred against. In that case,
- // this slim context should end up dealing with differences at buildContext()
- // time. This is a YANGTOOLS-1067 prerequisite (which will deal with what can and
- // cannot be shared across instances).
return Optional.of(parent.childCopyOf(this, type, targetModule));
case IGNORE:
return Optional.empty();
}
}
+ private boolean substatementsContextIndependent() {
+ // FIXME: YANGTOOLS-1195: we really want to compute (and cache) the summary for substatements.
+ //
+ // For now we just check if there are any substatements, but we really want to ask:
+ //
+ // Are all substatements (recursively) CONTEXT_INDEPENDENT as well?
+ //
+ // Which is something we want to compute once and store. This needs to be implemented.
+ return hasEmptySubstatements();
+ }
+
+ // FIXME: YANGTOOLS-1195: this method is unused, but should be called from InferredStatementContext at the very
+ // least. It should return @NonNull -- either 'E' or EffectiveStmtCtx.Current'. Perhaps its arguments need
+ // to be adjusted, too.
+ final void asEffectiveChildOf(final Mutable<?, ?, ?> parent, final CopyType type, final QNameModule targetModule) {
+ checkEffectiveModelCompleted(this);
+
+ final StatementSupport<A, D, E> support = definition.support();
+ final StmtContext<?, ?, ?> effective = support.effectiveCopyOf(this, parent, type, targetModule);
+ if (effective == this) {
+ LOG.debug("Should reuse {}", this);
+ return;
+ }
+
+ // FIXME: YANGTOOLS-1195: here is probably where we want to do some statement reuse: even if the parent is
+ // affected, some substatements may not -- in which case we want to reuse them. This
+ // probably needs to be a callout of some kind.
+ // FIXME: YANGTOOLS-1067: an incremental improvement to that is that if no substatements changed, we want to
+ // be reusing the entire List<EffectiveStatement> and pass that as substatements.
+ }
+
@Override
public final Mutable<?, ?, ?> childCopyOf(final StmtContext<?, ?, ?> stmt, final CopyType type,
final QNameModule targetModule) {
}
@Override
- public final StatementContextBase<A, D, E> replicaAsChildOf(final Mutable<?, ?, ?> parent) {
+ public final ReactorStmtCtx<A, D, E> replicaAsChildOf(final Mutable<?, ?, ?> parent) {
checkArgument(parent instanceof StatementContextBase, "Unsupported parent %s", parent);
return replicaAsChildOf((StatementContextBase<?, ?, ?>) parent);
}
- final @NonNull StatementContextBase<A, D, E> replicaAsChildOf(final StatementContextBase<?, ?, ?> stmt) {
+ final @NonNull ReplicaStatementContext<A, D, E> replicaAsChildOf(final StatementContextBase<?, ?, ?> stmt) {
return new ReplicaStatementContext<>(stmt, this);
}