}
private Optional<? extends Mutable<?, ?, ?>> copySubstatement(final Mutable<?, ?, ?> substatement) {
+ // FIXME: YANGTOOLS-1195: this is not exactly what we want to do here, because we are deling with two different
+ // requests: copy for inference purposes (this method), while we also copy for purposes
+ // of buildEffective() -- in which case we want to probably invoke asEffectiveChildOf()
+ // or similar
return substatement.copyAsChildOf(this, childCopyType, targetModule);
}
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));
}
- // ascertaining substatements could be quite costly, let's just fall through to declared copy and deal
- // shortcut it when we build the statements.
+
// 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) {
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
+import com.google.common.base.VerifyException;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.QNameModule;
}
@Override
- public CopyPolicy applyCopyPolicy(final Mutable<?, ?, ?> stmt, final Mutable<?, ?, ?> parent,
- final CopyType copyType, final QNameModule targetModule) {
+ public final CopyPolicy copyPolicy() {
return copyPolicy;
}
+ @Override
+ public final StmtContext<?, ?, ?> effectiveCopyOf(final StmtContext<?, ?, ?> stmt, final Mutable<?, ?, ?> parent,
+ final CopyType copyType, final QNameModule targetModule) {
+ switch (copyPolicy) {
+ case CONTEXT_INDEPENDENT:
+ return stmt;
+ case DECLARED_COPY:
+ // FIXME: YANGTOOLS-1195: this is too harsh, we need to make a callout to subclass methods so they
+ // actually examine the differences.
+ return parent.childCopyOf(stmt, copyType, targetModule);
+ default:
+ throw new VerifyException("Attempted to apply " + copyPolicy);
+ }
+ }
+
@Override
public void onStatementAdded(final StmtContext.Mutable<A, D, E> stmt) {
// NOOP for most implementations
}
@Override
- public CopyPolicy applyCopyPolicy(final Mutable<?, ?, ?> stmt, final Mutable<?, ?, ?> parent,
+ public CopyPolicy copyPolicy() {
+ return delegate().copyPolicy();
+ }
+
+ @Override
+ public StmtContext<?, ?, ?> effectiveCopyOf(final StmtContext<?, ?, ?> stmt, final Mutable<?, ?, ?> parent,
final CopyType copyType, final QNameModule targetModule) {
- return delegate().applyCopyPolicy(stmt, parent, copyType, targetModule);
+ return delegate().effectiveCopyOf(stmt, parent, copyType, targetModule);
}
}
@Nullable StatementSupport<?, ?, ?> getSupportSpecificForArgument(String argument);
/**
- * Determine reactor copy behavior of a statement instance. Statement support classes are required to determine
+ * Return this statement's {@link CopyPolicy}. This is a static value, reflecting how this statement reacts to being
+ * replicated to a different context, without reflecting on behaviour of potential substatements, which would come
+ * into play in something like:
+ *
+ * <pre>
+ * <code>
+ * module foo {
+ * namespace foo;
+ * prefix foo;
+ *
+ * extension note {
+ * argument string {
+ * type string {
+ * length 1..max;
+ * }
+ * }
+ * description "Can be used in description/reference statements to attach additional notes";
+ * }
+ *
+ * description "A nice module extending description statement semantics" {
+ * foo:note "We can now attach description/reference a note.";
+ * foo:note "Also another note";
+ * }
+ * }
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * In this scenario, it is the reactor's job to figure out what to do (like talking to substatements).
+ *
+ * @return This statement's copy policy
+ */
+ @NonNull CopyPolicy copyPolicy();
+
+ /**
+ * Determine reactor copy behaviour of a statement instance. Statement support classes are required to determine
* their operations with regard to their statements being replicated into different contexts, so that
* {@link Mutable} instances are not created when it is evident they are superfluous.
*
* the default namespace to parent's namespace, whereas {@code augment} does not.</li>
* </ul>
*
+ * <p>
+ * Implementations should return the context to use -- returning {@code stmt} if there is no change or a copy of it.
+ *
* @param stmt Context of statement to be copied statement
* @param parent Parent statement context
* @param copyType Type of copy being performed
* @param targetModule Target module, if present
- * @return Policy that needs to be applied to the copy operation of this statement.
+ * @return StmtContext holding the effective state
*/
- default @NonNull CopyPolicy applyCopyPolicy(final Mutable<?, ?, ?> stmt, final Mutable<?, ?, ?> parent,
- final CopyType copyType, @Nullable final QNameModule targetModule) {
- // Most of statement supports will just want to copy the statement
- // FIXME: YANGTOOLS-694: that is not strictly true. Subclasses of this should indicate if they are themselves
- // copy-sensitive:
- // 1) if they are not and cannot be targeted by inference, and all their current
- // substatements are also non-sensitive, we want to return the same context.
- // 2) if they are not and their current substatements are sensitive, we want to copy
- // as a lazily-instantiated interceptor to let it deal with substatements when needed
- // (YANGTOOLS-1067 prerequisite)
- // 3) otherwise perform this eager copy
- // return Optional.of(parent.childCopyOf(stmt, copyType, targetModule));
- return CopyPolicy.DECLARED_COPY;
- }
+ @NonNull StmtContext<?, ?, ?> effectiveCopyOf(StmtContext<?, ?, ?> stmt, Mutable<?, ?, ?> parent, CopyType copyType,
+ @Nullable QNameModule targetModule);
/**
* Given a raw string representation of an argument, try to use a shared representation.
/**
* Statement context copy policy, indicating how should reactor handle statement copy operations. Every statement
* copied by the reactor is subject to policy check done by
- * {@link StatementSupport#applyCopyPolicy(Mutable, Mutable, CopyType, QNameModule)}.
- *
+ * {@link StatementSupport#effectiveCopyOf(StmtContext, Mutable, CopyType, QNameModule)}.
*/
enum CopyPolicy {
/**