Move DeviateKind parsing
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / ModelActionBuilder.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.spi.meta;
9
10 import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.EFFECTIVE_MODEL;
11
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;
19
20
21 /**
22  * Builder for effective model inference action.
23  *
24  * Model inference action is core principle of transforming
25  * declared model into effective model.
26  *
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.
32  *
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
37  * action.
38  *
39  * <h2>Implementing inference action</h2>
40  *
41  * Effective inference action could always be splitted into two
42  * separate tasks:
43  * <ol>
44  * <li>Declaration of inference action and its prerequisites</li>
45  * <li>Execution of inference action</li>
46  * </ol>
47  * In order to declare inference action following steps needs
48  * to be taken:
49  *
50  * <ol>
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.
59  * </ol>
60  *
61  * Action will be executed when:
62  * <ul>
63  * <li> {@link InferenceAction#apply()} - all prerequisites (and declared forward references) are met,
64  * action could dereference them and start applying changes.
65  * </li>
66  * <li>{@link InferenceAction#prerequisiteFailed(Collection)} - semantic parser finished all other satisfied
67  * inference actions and some of declared prerequisites was still not met.
68  * </li>
69  * </ul>
70  *
71  * TODO: Insert real word example
72  *
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
78  * semantic parser.
79  *
80  * Also listening on multiple futures is costly, so we opted
81  * out of future and designed API, which later may introduce
82  * futures.
83  *
84  */
85 public interface ModelActionBuilder {
86
87     @FunctionalInterface
88     interface Prerequisite<T> extends Supplier<T> {
89         /**
90          * Returns associated prerequisite once it is resolved.
91          *
92          * @return associated prerequisite once it is resolved.
93          */
94         @Override
95         T get();
96     }
97
98     /**
99      * User-defined inference action.
100      *
101      */
102     interface InferenceAction {
103
104         /**
105          * Invoked once all prerequisites were met and forward references
106          * were resolved and inference action should be applied.
107          *
108          * Implementors may do necessary changes to mutable objects
109          * which were declared.
110          *
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.
114          */
115         void apply() throws InferenceException;
116
117         /**
118          * Invoked once one of prerequisites was not met,
119          * even after all other satisfiable inference actions were processed.
120          *
121          * Implementors MUST throw {@link InferenceException} if semantic processing
122          * of model should be stopped and failed.
123          *
124          * List of failed prerequisites should be used to select right message / error
125          * type to debug problem in YANG sources.
126          *
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.
131          */
132         void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException;
133     }
134
135     /**
136      * Action requires that the specified context transition to complete{@link ModelProcessingPhase#FULL_DECLARATION}
137      * phase.
138      *
139      * @param context Statement context which needs to
140      * @return A {@link Prerequisite} returning the declared statement of the specified context.
141      */
142     @Nonnull <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(StmtContext<?, ? extends D, ?> context);
143
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);
146
147     @Nonnull <K, N extends StatementNamespace<K, ?, ? >> Prerequisite<StmtContext<?,?,?>> requiresCtx(
148         StmtContext<?, ?, ?> context, Class<N> namespace, K key, ModelProcessingPhase phase);
149
150     default @Nonnull <T extends Mutable<?, ?, ?>> Prerequisite<T> mutatesEffectiveCtx(final T stmt) {
151         return mutatesCtx(stmt, EFFECTIVE_MODEL);
152     }
153
154     @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
155         Prerequisite<Mutable<?, ?, E>> mutatesEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
156
157     @Nonnull <C extends StmtContext.Mutable<?, ?, ?>, CT extends C> Prerequisite<C> mutatesCtx(CT root,
158             ModelProcessingPhase phase);
159
160     void apply(InferenceAction action) throws InferenceException;
161
162     /**
163      * @deprecated Undocumented method. Use at your own risk.
164      */
165     @Deprecated
166     @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
167         Prerequisite<D> requiresDeclared(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
168
169     /**
170      * @deprecated Undocumented method. Use at your own risk.
171      */
172     @Deprecated
173     @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
174         Prerequisite<StmtContext<?, D, ?>> requiresDeclaredCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
175
176     /**
177      * @deprecated Undocumented method. Use at your own risk.
178      */
179     @Deprecated
180     @Nonnull <E extends EffectiveStatement<?, ?>> Prerequisite<E> requiresEffective(
181             StmtContext<?, ?, ? extends E> stmt);
182
183     /**
184      * @deprecated Undocumented method. Use at your own risk.
185      */
186     @Deprecated
187     @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>>
188         Prerequisite<E> requiresEffective(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
189
190     /**
191      * @deprecated Undocumented method. Use at your own risk.
192      */
193     @Deprecated
194     @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>>
195     Prerequisite<StmtContext<?, ?, E>> requiresEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace,
196             K key);
197
198     /**
199      * @deprecated Undocumented method. Use at your own risk.
200      */
201     @Deprecated
202     @Nonnull <N extends IdentifierNamespace<?, ?>> Prerequisite<Mutable<?,?,?>> mutatesNs(
203             Mutable<?,?, ?> ctx, Class<N> namespace);
204 }