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 com.google.common.base.Supplier;
13 import java.util.Collection;
14 import javax.annotation.Nonnull;
15 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
16 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
17 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
18 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
22 * Builder for effective model inference action.
24 * Model inference action is core principle of transforming
25 * declared model into effective model.
27 * Since YANG allows forward references, some inference actions
28 * need to be taken at a later point, where reference is actually
29 * resolved. Referenced objects are not retrieved directly
30 * but are represented as {@link Prerequisite} (prerequisite) for
31 * inference action to be taken.
33 * Some existing YANG statements are more complex and also object,
34 * for which effective model may be inferred is also represented
35 * as {@link Prerequisite} which once, when reference is available
36 * will contain target context, which may be used for inference
39 * <h2>Implementing inference action</h2>
41 * Effective inference action could always be splitted into two
44 * <li>Declaration of inference action and its prerequisites</li>
45 * <li>Execution of inference action</li>
47 * In order to declare inference action following steps needs
51 * <li>Use {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)} to obtain
52 * {@link ModelActionBuilder}.
53 * <li>Use builder to specify concrete prerequisites of inference action
54 * (other statements, values from identifier namespaces)
55 * <li>Use builder to specify concrete set of nodes (or forward references to nodes)
56 * which will inference action mutate.
57 * <li>Use {@link #apply(InferenceAction)} with {@link InferenceAction} implementation
58 * to register inference action.
61 * Action will be executed when:
63 * <li> {@link InferenceAction#apply()} - all prerequisites (and declared forward references) are met,
64 * action could dereference them and start applying changes.
66 * <li>{@link InferenceAction#prerequisiteFailed(Collection)} - semantic parser finished all other satisfied
67 * inference actions and some of declared prerequisites was still not met.
71 * TODO: Insert real word example
73 * <h2>Design notes</h2>
74 * {@link java.util.concurrent.Future} seems as viable and more standard
75 * alternative to {@link Prerequisite}, but futures also carries
76 * promise that resolution of it is carried in other
77 * thread, which will actually put additional constraints on
80 * Also listening on multiple futures is costly, so we opted
81 * out of future and designed API, which later may introduce
85 public interface ModelActionBuilder {
88 interface Prerequisite<T> extends Supplier<T> {
90 * Returns associated prerequisite once it is resolved.
92 * @return associated prerequisite once it is resolved.
99 * User-defined inference action.
102 interface InferenceAction {
105 * Invoked once all prerequisites were met and forward references
106 * were resolved and inference action should be applied.
108 * Implementors may do necessary changes to mutable objects
109 * which were declared.
111 * @throws InferenceException If inference action can not be processed.
112 * Note that this exception be used for user to debug YANG sources,
113 * so should provide helpful context to fix issue in sources.
115 void apply() throws InferenceException;
118 * Invoked once one of prerequisites was not met,
119 * even after all other satisfiable inference actions were processed.
121 * Implementors MUST throw {@link InferenceException} if semantic processing
122 * of model should be stopped and failed.
124 * List of failed prerequisites should be used to select right message / error
125 * type to debug problem in YANG sources.
127 * @param failed collection of prerequisites which were not met
128 * @throws InferenceException If inference action can not be processed.
129 * Note that this exception be used for user to debug YANG sources,
130 * so should provide helpful context to fix issue in sources.
132 void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException;
136 * Action requires that the specified context transition to complete{@link ModelProcessingPhase#FULL_DECLARATION}
139 * @param context Statement context which needs to
140 * @return A {@link Prerequisite} returning the declared statement of the specified context.
142 @Nonnull <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(StmtContext<?, ? extends D, ?> context);
144 @Nonnull <A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
145 Prerequisite<StmtContext<A, D, E>> requiresCtx(StmtContext<A, D, E> context, ModelProcessingPhase phase);
147 @Nonnull <K, N extends StatementNamespace<K, ?, ? >> Prerequisite<StmtContext<?,?,?>> requiresCtx(
148 StmtContext<?, ?, ?> context, Class<N> namespace, K key, ModelProcessingPhase phase);
150 default @Nonnull <T extends Mutable<?, ?, ?>> Prerequisite<T> mutatesEffectiveCtx(final T stmt) {
151 return mutatesCtx(stmt, EFFECTIVE_MODEL);
154 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
155 Prerequisite<Mutable<?, ?, E>> mutatesEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
157 @Nonnull <C extends StmtContext.Mutable<?, ?, ?>, CT extends C> Prerequisite<C> mutatesCtx(CT root,
158 ModelProcessingPhase phase);
160 void apply(InferenceAction action) throws InferenceException;
163 * @deprecated Undocumented method. Use at your own risk.
166 @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
167 Prerequisite<D> requiresDeclared(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
170 * @deprecated Undocumented method. Use at your own risk.
173 @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
174 Prerequisite<StmtContext<?, D, ?>> requiresDeclaredCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
177 * @deprecated Undocumented method. Use at your own risk.
180 @Nonnull <E extends EffectiveStatement<?, ?>> Prerequisite<E> requiresEffective(
181 StmtContext<?, ?, ? extends E> stmt);
184 * @deprecated Undocumented method. Use at your own risk.
187 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>>
188 Prerequisite<E> requiresEffective(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
191 * @deprecated Undocumented method. Use at your own risk.
194 @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>>
195 Prerequisite<StmtContext<?, ?, E>> requiresEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace,
199 * @deprecated Undocumented method. Use at your own risk.
202 @Nonnull <N extends IdentifierNamespace<?, ?>> Prerequisite<Mutable<?,?,?>> mutatesNs(
203 Mutable<?,?, ?> ctx, Class<N> namespace);