X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-spi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fspi%2Fmeta%2FAbstractStatementSupport.java;h=f8ddbf3e0d3619f3d391776f325e787b1e502c4b;hb=b0ee110abbdefb8c84e032ae4a6ae73d8df99ba9;hp=a12cd19660ed4fec5139d2c2b8bc4b15433beb30;hpb=c8668229ad6e73d5ae03a52f4b87e8e4d2a67c6e;p=yangtools.git diff --git a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java index a12cd19660..f8ddbf3e0d 100644 --- a/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java +++ b/yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java @@ -10,11 +10,16 @@ package org.opendaylight.yangtools.yang.parser.spi.meta; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; +import com.google.common.annotations.Beta; +import com.google.common.base.VerifyException; +import java.util.Collection; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yangtools.concepts.Immutable; 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.EffectiveStmtCtx.Current; /** * Class providing necessary support for processing a YANG statement. This class is intended to be subclassed @@ -26,19 +31,208 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; */ public abstract class AbstractStatementSupport, E extends EffectiveStatement> implements StatementDefinition, StatementFactory, StatementSupport { + /** + * A baseline class for implementing the {@link StatementFactory#canReuseCurrent(Current, Current, Collection)} + * contract in a manner which is consistent with a statement's {@link CopyPolicy}. + * + * @param Argument type + * @param Declared Statement representation + */ + public abstract static class StatementPolicy> implements Immutable { + final @NonNull CopyPolicy copyPolicy; + + StatementPolicy(final CopyPolicy copyPolicy) { + this.copyPolicy = requireNonNull(copyPolicy); + } + + /** + * Return an {@link StatementPolicy} for {@link CopyPolicy#CONTEXT_INDEPENDENT}. + * + * @param Argument type + * @param Declared Statement representation + * @return Context-independent policy + */ + @SuppressWarnings("unchecked") + public static final > @NonNull StatementPolicy contextIndependent() { + return (StatementPolicy) AlwaysReuse.CONTEXT_INDEPENDENT; + } + + /** + * Return an {@link StatementPolicy} for {@link CopyPolicy#IGNORE}. + * + * @param Argument type + * @param Declared Statement representation + * @return Ignoring policy + */ + @SuppressWarnings("unchecked") + public static final > @NonNull StatementPolicy ignore() { + return (StatementPolicy) AlwaysFail.IGNORE; + } + + /** + * Return an {@link StatementPolicy} for {@link CopyPolicy#REJECT}. + * + * @param Argument type + * @param Declared Statement representation + * @return Rejecting statement policy + */ + @SuppressWarnings("unchecked") + public static final > @NonNull StatementPolicy reject() { + return (StatementPolicy) AlwaysFail.REJECT; + } + + /** + * Return an {@link StatementPolicy} for {@link CopyPolicy#DECLARED_COPY}, deferring to a + * {@link StatementEquality} for individual decisions. + * + * @param Argument type + * @param Declared Statement representation + * @param equality {@link StatementEquality} to apply to effective statements + * @return Rejecting statement policy + */ + public static final > @NonNull StatementPolicy copyDeclared( + final @NonNull StatementEquality equality) { + return new EqualSemantics<>(equality); + } + + abstract boolean canReuseCurrent(@NonNull Current copy, @NonNull Current current, + @NonNull Collection> substatements); + + @Deprecated + @SuppressWarnings("unchecked") + static > StatementPolicy compat(final CopyPolicy copyPolicy) { + switch (copyPolicy) { + case CONTEXT_INDEPENDENT: + return contextIndependent(); + case DECLARED_COPY: + return (StatementPolicy) AlwaysCopy.DECLARED_COPY; + case IGNORE: + return ignore(); + case REJECT: + return reject(); + default: + throw new IllegalStateException("Unsupported policy " + copyPolicy); + } + } + + private static final class AlwaysCopy> extends StatementPolicy { + @Deprecated + static final @NonNull AlwaysCopy DECLARED_COPY = new AlwaysCopy<>(CopyPolicy.DECLARED_COPY); + + AlwaysCopy(final CopyPolicy copyPolicy) { + super(copyPolicy); + } + + @Override + boolean canReuseCurrent(final Current copy, final Current current, + final Collection> substatements) { + return false; + } + } + + private static final class AlwaysReuse> extends StatementPolicy { + static final @NonNull AlwaysReuse CONTEXT_INDEPENDENT = + new AlwaysReuse<>(CopyPolicy.CONTEXT_INDEPENDENT); + + private AlwaysReuse(final CopyPolicy copyPolicy) { + super(copyPolicy); + } + + @Override + boolean canReuseCurrent(final Current copy, final Current current, + final Collection> substatements) { + return true; + } + } + + private static final class AlwaysFail> extends StatementPolicy { + static final @NonNull AlwaysFail IGNORE = new AlwaysFail<>(CopyPolicy.IGNORE); + static final @NonNull AlwaysFail REJECT = new AlwaysFail<>(CopyPolicy.REJECT); + + private AlwaysFail(final CopyPolicy copyPolicy) { + super(copyPolicy); + } + + @Override + boolean canReuseCurrent(final Current copy, final Current current, + final Collection> substatements) { + throw new VerifyException("This implementation should never be invoked"); + } + } + + private static final class EqualSemantics> extends StatementPolicy { + private final @NonNull StatementEquality equality; + EqualSemantics(final @NonNull StatementEquality equality) { + super(CopyPolicy.DECLARED_COPY); + this.equality = requireNonNull(equality); + } + + @Override + boolean canReuseCurrent(final Current copy, final Current current, + final Collection> substatements) { + return equality.canReuseCurrent(copy, current, substatements); + } + } + } + + /** + * Abstract base class for comparators associated with statements with a {@link CopyPolicy#DECLARED_COPY} copy + * policy. + * + * @param Argument type + * @param Declared Statement representation + */ + @FunctionalInterface + public interface StatementEquality> { + /** + * Determine whether {@code current} statement has the same semantics as the provided copy. See the contract + * specification of {@link StatementFactory#canReuseCurrent(Current, Current, Collection)}. + * + * @param copy Copy of current effective context + * @param current Current effective context + * @param substatements Current effective substatements + * @return True if {@code current} can be reused in place of {@code copy}, false if the copy needs to be used. + */ + boolean canReuseCurrent(@NonNull Current copy, @NonNull Current current, + @NonNull Collection> substatements); + } + + private final @NonNull StatementPolicy policy; private final @NonNull StatementDefinition type; + private final @NonNull CopyPolicy copyPolicy; - protected AbstractStatementSupport(final StatementDefinition publicDefinition) { + @Beta + protected AbstractStatementSupport(final StatementDefinition publicDefinition, final StatementPolicy policy) { this.type = requireNonNull(publicDefinition); + this.policy = requireNonNull(policy); + this.copyPolicy = policy.copyPolicy; checkArgument(publicDefinition != this); } + @Beta + @Deprecated + // FIXME: remove this constructor + protected AbstractStatementSupport(final StatementDefinition publicDefinition, final CopyPolicy copyPolicy) { + this(publicDefinition, StatementPolicy.compat(copyPolicy)); + } + @Override public final StatementDefinition getPublicView() { return type; } + @Override + public final CopyPolicy copyPolicy() { + return copyPolicy; + } + + @Override + public final boolean canReuseCurrent(final Current copy, final Current current, + final Collection> substatements) { + return policy.canReuseCurrent(copy, current, substatements); + } + @Override public void onStatementAdded(final StmtContext.Mutable stmt) { // NOOP for most implementations @@ -97,15 +291,13 @@ public abstract class AbstractStatementSupport @Override public boolean hasArgumentSpecificSupports() { - // Most of statement supports don't have any argument specific - // supports, so return 'false'. + // Most of statement supports don't have any argument specific supports, so return 'false'. return false; } @Override public StatementSupport getSupportSpecificForArgument(final String argument) { - // Most of statement supports don't have any argument specific - // supports, so return null. + // Most of statement supports don't have any argument specific supports, so return null. return null; }