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 org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.EFFECTIVE_MODEL;
12 import java.util.Collection;
13 import javax.annotation.Nonnull;
14 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
15 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
16 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
17 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
20 * Builder for effective model inference action. Model inference action is core principle of transforming
21 * declared model into effective model.
24 * Since YANG allows forward references, some inference actions need to be taken at a later point, where reference is
25 * actually resolved. Referenced objects are not retrieved directly but are represented as {@link Prerequisite}
26 * (prerequisite) for inference action to be taken.
29 * Some existing YANG statements are more complex and also object, for which effective model may be inferred is also
30 * represented as a {@link Prerequisite} which, when reference is available, will contain target context, which may be
31 * used for inference action.
33 * <h2>Implementing inference action</h2>
34 * Effective inference action could always be splitted into two separate tasks:
36 * <li>Declaration of inference action and its prerequisites</li>
37 * <li>Execution of inference action</li>
41 * In order to declare inference action following steps needs
44 * <li>Use {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)} to obtain
45 * {@link ModelActionBuilder}.
46 * <li>Use builder to specify concrete prerequisites of inference action
47 * (other statements, values from identifier namespaces)
48 * <li>Use builder to specify concrete set of nodes (or forward references to nodes)
49 * which will inference action mutate.
50 * <li>Use {@link #apply(InferenceAction)} with {@link InferenceAction} implementation
51 * to register inference action.
55 * An action will be executed when:
57 * <li> {@link InferenceAction#apply(InferenceContext)} - all prerequisites (and declared forward references) are met,
58 * action could dereference them and start applying changes.
60 * <li>{@link InferenceAction#prerequisiteFailed(Collection)} - semantic parser finished all other satisfied
61 * inference actions and some of declared prerequisites was still not met.
66 * TODO: Insert real word example
68 * <h2>Design notes</h2>
69 * {@link java.util.concurrent.Future} seems as viable and more standard alternative to {@link Prerequisite}, but
70 * Futures also carries promise that resolution of it is carried in other thread, which will actually put additional
71 * constraints on semantic parser.
74 * Also listening on multiple futures is costly, so we opted out of future and designed API, which later may introduce
77 public interface ModelActionBuilder {
78 interface InferenceContext {
83 interface Prerequisite<T> {
85 * Returns associated prerequisite once it is resolved.
87 * @param ctx Inference context in which the prerequisite was satisfied
88 * @return associated prerequisite once it is resolved.
90 T resolve(InferenceContext ctx);
94 * User-defined inference action.
96 interface InferenceAction {
99 * Invoked once all prerequisites were met and forward references were resolved and inference action should be
100 * applied. Implementors may perform necessary changes to mutable objects which were declared.
102 * @throws InferenceException If inference action can not be processed.
103 * Note that this exception be used for user to debug YANG sources,
104 * so should provide helpful context to fix issue in sources.
106 void apply(InferenceContext ctx) throws InferenceException;
109 * Invoked once one of prerequisites was not met, even after all other satisfiable inference actions were
113 * Implementors MUST throw {@link InferenceException} if semantic processing of model should be stopped
117 * List of failed prerequisites should be used to select right message / error type to debug problem in YANG
120 * @param failed collection of prerequisites which were not met
121 * @throws InferenceException If inference action can not be processed. Note that this exception be used
122 * by user to debug YANG sources, hence it should provide helpful context to fix
123 * the issue in sources.
125 void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException;
129 * Action requires that the specified context transition to complete {@link ModelProcessingPhase#FULL_DECLARATION}
130 * phase and produce a declared statement.
132 * @param context Statement context which needs to complete the transition.
133 * @return A {@link Prerequisite} returning the declared statement of the requested context.
135 @Nonnull <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(StmtContext<?, ? extends D, ?> context);
138 * Create a requirement on specified statement to be declared.
140 * @deprecated Undocumented method. Use at your own risk.
143 @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
144 Prerequisite<D> requiresDeclared(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
147 * Action requires that the specified context completes specified phase.
149 * @param context Statement context which needs to complete the transition.
150 * @param phase ModelProcessingPhase which must have completed
151 * @return A {@link Prerequisite} returning the requested context.
153 @Nonnull <A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
154 Prerequisite<StmtContext<A, D, E>> requiresCtx(StmtContext<A, D, E> context, ModelProcessingPhase phase);
156 @Nonnull <K, N extends StatementNamespace<K, ?, ?>> Prerequisite<StmtContext<?, ?, ?>> requiresCtx(
157 StmtContext<?, ?, ?> context, Class<N> namespace, K key, ModelProcessingPhase phase);
159 @Nonnull <K, N extends StatementNamespace<K, ?, ?>> Prerequisite<StmtContext<?, ?, ?>> requiresCtx(
160 StmtContext<?, ?, ?> context, Class<N> namespace, NamespaceKeyCriterion<K> criterion,
161 ModelProcessingPhase phase);
163 default @Nonnull <T extends Mutable<?, ?, ?>> Prerequisite<T> mutatesEffectiveCtx(final T stmt) {
164 return mutatesCtx(stmt, EFFECTIVE_MODEL);
167 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
168 Prerequisite<Mutable<?, ?, E>> mutatesEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
170 @Nonnull <C extends StmtContext.Mutable<?, ?, ?>, CT extends C> Prerequisite<C> mutatesCtx(CT root,
171 ModelProcessingPhase phase);
173 void apply(InferenceAction action) throws InferenceException;
176 * Create a requirement on specified statement context to be declared.
178 * @deprecated Undocumented method. Use at your own risk.
181 @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
182 Prerequisite<StmtContext<?, D, ?>> requiresDeclaredCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
185 * Create a requirement on specified statement to become effective.
187 * @deprecated Undocumented method. Use at your own risk.
190 @Nonnull <E extends EffectiveStatement<?, ?>> Prerequisite<E> requiresEffective(
191 StmtContext<?, ?, ? extends E> stmt);
194 * Create a requirement on specified statement to become effective.
196 * @deprecated Undocumented method. Use at your own risk.
199 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>>
200 Prerequisite<E> requiresEffective(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
203 * Create a requirement on specified statement context to become effective.
205 * @deprecated Undocumented method. Use at your own risk.
208 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>>
209 Prerequisite<StmtContext<?, ?, E>> requiresEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace,
213 * Mark the fact that this action is mutating a namespace.
215 * @deprecated Undocumented method. Use at your own risk.
218 @Nonnull <N extends IdentifierNamespace<?, ?>> Prerequisite<Mutable<?,?,?>> mutatesNs(
219 Mutable<?,?, ?> ctx, Class<N> namespace);