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;
21 * Builder for effective model inference action.
23 * Model inference action is core principle of transforming
24 * declared model into effective model.
26 * Since YANG allows forward references, some inference actions
27 * need to be taken at a later point, where reference is actually
28 * resolved. Referenced objects are not retrieved directly
29 * but are represented as {@link Prerequisite} (prerequisite) for
30 * inference action to be taken.
32 * Some existing YANG statements are more complex and also object,
33 * for which effective model may be inferred is also represented
34 * as {@link Prerequisite} which once, when reference is available
35 * will contain target context, which may be used for inference
38 * <h2>Implementing inference action</h2>
40 * Effective inference action could always be splitted into two
43 * <li>Declaration of inference action and its prerequisites</li>
44 * <li>Execution of inference action</li>
46 * In order to declare inference action following steps needs
50 * <li>Use {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)} to obtain
51 * {@link ModelActionBuilder}.
52 * <li>Use builder to specify concrete prerequisites of inference action
53 * (other statements, values from identifier namespaces)
54 * <li>Use builder to specify concrete set of nodes (or forward references to nodes)
55 * which will inference action mutate.
56 * <li>Use {@link #apply(InferenceAction)} with {@link InferenceAction} implementation
57 * to register inference action.
60 * Action will be executed when:
62 * <li> {@link InferenceAction#apply(InferenceContext)} - all prerequisites (and declared forward references) are met,
63 * action could dereference them and start applying changes.
65 * <li>{@link InferenceAction#prerequisiteFailed(Collection)} - semantic parser finished all other satisfied
66 * inference actions and some of declared prerequisites was still not met.
70 * TODO: Insert real word example
72 * <h2>Design notes</h2>
73 * {@link java.util.concurrent.Future} seems as viable and more standard
74 * alternative to {@link Prerequisite}, but futures also carries
75 * promise that resolution of it is carried in other
76 * thread, which will actually put additional constraints on
79 * Also listening on multiple futures is costly, so we opted
80 * out of future and designed API, which later may introduce
84 public interface ModelActionBuilder {
85 interface InferenceContext {
90 interface Prerequisite<T> {
92 * Returns associated prerequisite once it is resolved.
94 * @param ctx Inference context in which the prerequisite was satisfied
95 * @return associated prerequisite once it is resolved.
97 T resolve(InferenceContext ctx);
101 * User-defined inference action.
103 interface InferenceAction {
106 * Invoked once all prerequisites were met and forward references
107 * were resolved and inference action should be applied.
109 * Implementors may do necessary changes to mutable objects
110 * which were declared.
112 * @throws InferenceException If inference action can not be processed.
113 * Note that this exception be used for user to debug YANG sources,
114 * so should provide helpful context to fix issue in sources.
116 void apply(InferenceContext ctx) throws InferenceException;
119 * Invoked once one of prerequisites was not met,
120 * even after all other satisfiable inference actions were processed.
122 * Implementors MUST throw {@link InferenceException} if semantic processing
123 * of model should be stopped and failed.
125 * List of failed prerequisites should be used to select right message / error
126 * type to debug problem in YANG sources.
128 * @param failed collection of prerequisites which were not met
129 * @throws InferenceException If inference action can not be processed.
130 * Note that this exception be used for user to debug YANG sources,
131 * so should provide helpful context to fix issue in sources.
133 void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException;
137 * Action requires that the specified context transition to complete {@link ModelProcessingPhase#FULL_DECLARATION}
138 * phase and produce a declared statement.
140 * @param context Statement context which needs to complete the transition.
141 * @return A {@link Prerequisite} returning the declared statement of the requested context.
143 @Nonnull <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(StmtContext<?, ? extends D, ?> context);
146 * Action requires that the specified context completes specified phase.
148 * @param context Statement context which needs to complete the transition.
149 * @param phase ModelProcessingPhase which must have completed
150 * @return A {@link Prerequisite} returning the requested context.
152 @Nonnull <A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
153 Prerequisite<StmtContext<A, D, E>> requiresCtx(StmtContext<A, D, E> context, ModelProcessingPhase phase);
155 @Nonnull <K, N extends StatementNamespace<K, ?, ? >> Prerequisite<StmtContext<?,?,?>> requiresCtx(
156 StmtContext<?, ?, ?> context, Class<N> namespace, K key, ModelProcessingPhase phase);
158 default @Nonnull <T extends Mutable<?, ?, ?>> Prerequisite<T> mutatesEffectiveCtx(final T stmt) {
159 return mutatesCtx(stmt, EFFECTIVE_MODEL);
162 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
163 Prerequisite<Mutable<?, ?, E>> mutatesEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
165 @Nonnull <C extends StmtContext.Mutable<?, ?, ?>, CT extends C> Prerequisite<C> mutatesCtx(CT root,
166 ModelProcessingPhase phase);
168 void apply(InferenceAction action) throws InferenceException;
171 * @deprecated Undocumented method. Use at your own risk.
174 @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
175 Prerequisite<D> requiresDeclared(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
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 * @deprecated Undocumented method. Use at your own risk.
188 @Nonnull <E extends EffectiveStatement<?, ?>> Prerequisite<E> requiresEffective(
189 StmtContext<?, ?, ? extends E> stmt);
192 * @deprecated Undocumented method. Use at your own risk.
195 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>>
196 Prerequisite<E> requiresEffective(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
199 * @deprecated Undocumented method. Use at your own risk.
202 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>>
203 Prerequisite<StmtContext<?, ?, E>> requiresEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace,
207 * @deprecated Undocumented method. Use at your own risk.
210 @Nonnull <N extends IdentifierNamespace<?, ?>> Prerequisite<Mutable<?,?,?>> mutatesNs(
211 Mutable<?,?, ?> ctx, Class<N> namespace);