2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.spi.meta;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.annotations.Beta;
14 import com.google.common.base.VerifyException;
15 import java.util.Collection;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.yangtools.concepts.Immutable;
19 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
20 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
21 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
25 * Class providing necessary support for processing a YANG statement. This class is intended to be subclassed
26 * by developers who want to add semantic support for a statement to a parser reactor.
28 * @param <A> Argument type
29 * @param <D> Declared Statement representation
30 * @param <E> Effective Statement representation
32 public abstract class AbstractStatementSupport<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
33 implements StatementDefinition, StatementFactory<A, D, E>, StatementSupport<A, D, E> {
35 * A baseline class for implementing the {@link StatementFactory#canReuseCurrent(Current, Current, Collection)}
36 * contract in a manner which is consistent with a statement's {@link CopyPolicy}.
38 * @param <A> Argument type
39 * @param <D> Declared Statement representation
41 public abstract static class StatementPolicy<A, D extends DeclaredStatement<A>> implements Immutable {
42 final @NonNull CopyPolicy copyPolicy;
44 StatementPolicy(final CopyPolicy copyPolicy) {
45 this.copyPolicy = requireNonNull(copyPolicy);
49 * Return an {@link StatementPolicy} for {@link CopyPolicy#CONTEXT_INDEPENDENT}.
51 * @param <A> Argument type
52 * @param <D> Declared Statement representation
53 * @return Context-independent policy
55 @SuppressWarnings("unchecked")
56 public static final <A, D extends DeclaredStatement<A>> @NonNull StatementPolicy<A, D> contextIndependent() {
57 return (StatementPolicy<A, D>) AlwaysReuse.CONTEXT_INDEPENDENT;
61 * Return an {@link StatementPolicy} for {@link CopyPolicy#IGNORE}.
63 * @param <A> Argument type
64 * @param <D> Declared Statement representation
65 * @return Ignoring policy
67 @SuppressWarnings("unchecked")
68 public static final <A, D extends DeclaredStatement<A>> @NonNull StatementPolicy<A, D> ignore() {
69 return (StatementPolicy<A, D>) AlwaysFail.IGNORE;
73 * Return an {@link StatementPolicy} for {@link CopyPolicy#REJECT}.
75 * @param <A> Argument type
76 * @param <D> Declared Statement representation
77 * @return Rejecting statement policy
79 @SuppressWarnings("unchecked")
80 public static final <A, D extends DeclaredStatement<A>> @NonNull StatementPolicy<A, D> reject() {
81 return (StatementPolicy<A, D>) AlwaysFail.REJECT;
85 * Return an {@link StatementPolicy} for {@link CopyPolicy#DECLARED_COPY}, deferring to a
86 * {@link StatementEquality} for individual decisions.
88 * @param <A> Argument type
89 * @param <D> Declared Statement representation
90 * @param equality {@link StatementEquality} to apply to effective statements
91 * @return Rejecting statement policy
93 public static final <A, D extends DeclaredStatement<A>> @NonNull StatementPolicy<A, D> copyDeclared(
94 final @NonNull StatementEquality<A, D> equality) {
95 return new EqualSemantics<>(equality);
98 abstract boolean canReuseCurrent(@NonNull Current<A, D> copy, @NonNull Current<A, D> current,
99 @NonNull Collection<? extends EffectiveStatement<?, ?>> substatements);
102 @SuppressWarnings("unchecked")
103 static <A, D extends DeclaredStatement<A>> StatementPolicy<A, D> compat(final CopyPolicy copyPolicy) {
104 switch (copyPolicy) {
105 case CONTEXT_INDEPENDENT:
106 return contextIndependent();
108 return (StatementPolicy<A, D>) AlwaysCopy.DECLARED_COPY;
114 throw new IllegalStateException("Unsupported policy " + copyPolicy);
118 private static final class AlwaysCopy<A, D extends DeclaredStatement<A>> extends StatementPolicy<A, D> {
120 static final @NonNull AlwaysCopy<?, ?> DECLARED_COPY = new AlwaysCopy<>(CopyPolicy.DECLARED_COPY);
122 AlwaysCopy(final CopyPolicy copyPolicy) {
127 boolean canReuseCurrent(final Current<A, D> copy, final Current<A, D> current,
128 final Collection<? extends EffectiveStatement<?, ?>> substatements) {
133 private static final class AlwaysReuse<A, D extends DeclaredStatement<A>> extends StatementPolicy<A, D> {
134 static final @NonNull AlwaysReuse<?, ?> CONTEXT_INDEPENDENT =
135 new AlwaysReuse<>(CopyPolicy.CONTEXT_INDEPENDENT);
137 private AlwaysReuse(final CopyPolicy copyPolicy) {
142 boolean canReuseCurrent(final Current<A, D> copy, final Current<A, D> current,
143 final Collection<? extends EffectiveStatement<?, ?>> substatements) {
148 private static final class AlwaysFail<A, D extends DeclaredStatement<A>> extends StatementPolicy<A, D> {
149 static final @NonNull AlwaysFail<?, ?> IGNORE = new AlwaysFail<>(CopyPolicy.IGNORE);
150 static final @NonNull AlwaysFail<?, ?> REJECT = new AlwaysFail<>(CopyPolicy.REJECT);
152 private AlwaysFail(final CopyPolicy copyPolicy) {
157 boolean canReuseCurrent(final Current<A, D> copy, final Current<A, D> current,
158 final Collection<? extends EffectiveStatement<?, ?>> substatements) {
159 throw new VerifyException("This implementation should never be invoked");
163 private static final class EqualSemantics<A, D extends DeclaredStatement<A>> extends StatementPolicy<A, D> {
164 private final @NonNull StatementEquality<A, D> equality;
166 EqualSemantics(final @NonNull StatementEquality<A, D> equality) {
167 super(CopyPolicy.DECLARED_COPY);
168 this.equality = requireNonNull(equality);
172 boolean canReuseCurrent(final Current<A, D> copy, final Current<A, D> current,
173 final Collection<? extends EffectiveStatement<?, ?>> substatements) {
174 return equality.canReuseCurrent(copy, current, substatements);
180 * Abstract base class for comparators associated with statements with a {@link CopyPolicy#DECLARED_COPY} copy
183 * @param <A> Argument type
184 * @param <D> Declared Statement representation
187 public interface StatementEquality<A, D extends DeclaredStatement<A>> {
189 * Determine whether {@code current} statement has the same semantics as the provided copy. See the contract
190 * specification of {@link StatementFactory#canReuseCurrent(Current, Current, Collection)}.
192 * @param copy Copy of current effective context
193 * @param current Current effective context
194 * @param substatements Current effective substatements
195 * @return True if {@code current} can be reused in place of {@code copy}, false if the copy needs to be used.
197 boolean canReuseCurrent(@NonNull Current<A, D> copy, @NonNull Current<A, D> current,
198 @NonNull Collection<? extends EffectiveStatement<?, ?>> substatements);
201 private final @NonNull StatementPolicy<A, D> policy;
202 private final @NonNull StatementDefinition type;
203 private final @NonNull CopyPolicy copyPolicy;
206 protected AbstractStatementSupport(final StatementDefinition publicDefinition, final StatementPolicy<A, D> policy) {
207 this.type = requireNonNull(publicDefinition);
208 this.policy = requireNonNull(policy);
209 this.copyPolicy = policy.copyPolicy;
210 checkArgument(publicDefinition != this);
215 // FIXME: remove this constructor
216 protected AbstractStatementSupport(final StatementDefinition publicDefinition, final CopyPolicy copyPolicy) {
217 this(publicDefinition, StatementPolicy.compat(copyPolicy));
221 public final StatementDefinition getPublicView() {
226 public final CopyPolicy copyPolicy() {
231 public final boolean canReuseCurrent(final Current<A, D> copy, final Current<A, D> current,
232 final Collection<? extends EffectiveStatement<?, ?>> substatements) {
233 return policy.canReuseCurrent(copy, current, substatements);
237 public void onStatementAdded(final StmtContext.Mutable<A, D, E> stmt) {
238 // NOOP for most implementations
245 * Subclasses of this class may override this method to perform actions on this event or register a modification
246 * action using {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
249 public void onPreLinkageDeclared(final StmtContext.Mutable<A, D, E> stmt) {
250 // NOOP for most implementations
257 * Subclasses of this class may override this method to perform actions on this event or register a modification
258 * action using {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
261 public void onLinkageDeclared(final StmtContext.Mutable<A, D, E> stmt) {
262 // NOOP for most implementations
269 * Subclasses of this class may override this method to perform actions on this event or register a modification
270 * action using {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
273 public void onStatementDefinitionDeclared(final StmtContext.Mutable<A, D, E> stmt) {
274 // NOOP for most implementations
281 * Subclasses of this class may override this method to perform actions on this event or register a modification
282 * action using {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
285 public void onFullDefinitionDeclared(final StmtContext.Mutable<A, D, E> stmt) {
286 final SubstatementValidator validator = getSubstatementValidator();
287 if (validator != null) {
288 validator.validate(stmt);
293 public boolean hasArgumentSpecificSupports() {
294 // Most of statement supports don't have any argument specific supports, so return 'false'.
299 public StatementSupport<?, ?, ?> getSupportSpecificForArgument(final String argument) {
300 // Most of statement supports don't have any argument specific supports, so return null.
305 * Returns corresponding substatement validator of a statement support.
307 * @return substatement validator or null, if substatement validator is not defined
309 protected abstract @Nullable SubstatementValidator getSubstatementValidator();