Prune StmtContext migration methods
[yangtools.git] / parser / yang-parser-spi / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / StmtContext.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 com.google.common.base.Verify.verifyNotNull;
11
12 import com.google.common.annotations.Beta;
13 import com.google.common.base.VerifyException;
14 import com.google.common.collect.Iterables;
15 import com.google.common.collect.Streams;
16 import java.util.Collection;
17 import java.util.Optional;
18 import java.util.stream.Stream;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.opendaylight.yangtools.yang.common.QNameModule;
22 import org.opendaylight.yangtools.yang.common.YangVersion;
23 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
24 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
26 import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin;
27 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
28
29 /**
30  * An inference context associated with an instance of a statement.
31  *
32  * @param <A> Argument type
33  * @param <D> Declared Statement representation
34  * @param <E> Effective Statement representation
35  */
36 public interface StmtContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
37         extends NamespaceStmtCtx, BoundStmtCtxCompat<A, D> {
38     @Deprecated(forRemoval = true)
39     default @NonNull StatementOrigin getStatementSource() {
40         return origin();
41     }
42
43     /**
44      * Return the parent statement context, or null if this is the root statement.
45      *
46      * @return context of parent of statement, or null if this is the root statement.
47      */
48     @Nullable StmtContext<?, ?, ?> getParentContext();
49
50     /**
51      * Return the parent statement context, forcing a VerifyException if this is the root statement.
52      *
53      * @return context of parent of statement
54      * @throws VerifyException if this statement is the root statement
55      */
56     default @NonNull StmtContext<?, ?, ?> coerceParentContext() {
57         return verifyNotNull(getParentContext(), "Root context %s does not have a parent", this);
58     }
59
60     /**
61      * Returns the model root for this statement.
62      *
63      * @return root context of statement
64      */
65     @NonNull RootStmtContext<?, ?, ?> getRoot();
66
67     /**
68      * Return declared substatements. These are the statements which are explicitly written in the source model, but
69      * reflect implicit containment statements as well. To but that statement into practical terms, this snippet:
70      * <pre>
71      *   <code>
72      *     choice foo {
73      *       container bar;
74      *     }
75      *   </code>
76      * </pre>
77      * reports the same structure as the canonical verbose equivalent:
78      * <pre>
79      *   <code>
80      *     choice foo {
81      *       case bar {
82      *         container bar;
83      *       }
84      *     }
85      *   </code>
86      * </pre>
87      * Returned collection is therefore well suited for reasoning about the schema tree. It is not appropriate for
88      * populating populating {@link DeclaredStatement#declaredSubstatements()}.
89      *
90      * @return Collection of declared substatements
91      */
92     @NonNull Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements();
93
94     /**
95      * Return effective substatements. These are the statements which are added as this statement's substatements
96      * complete their effective model phase.
97      *
98      * @return Collection of declared substatements
99      */
100     @NonNull Collection<? extends StmtContext<?, ?, ?>> effectiveSubstatements();
101
102     default Iterable<? extends StmtContext<?, ?, ?>> allSubstatements() {
103         return Iterables.concat(declaredSubstatements(), effectiveSubstatements());
104     }
105
106     default Stream<? extends StmtContext<?, ?, ?>> allSubstatementsStream() {
107         return Streams.concat(declaredSubstatements().stream(), effectiveSubstatements().stream());
108     }
109
110     /**
111      * Return the {@link EffectiveStatement} for statement context, creating it if required. Implementations of this
112      * method are required to memoize the returned object, so that subsequent invocation return the same object.
113      *
114      * <p>
115      * If {@link #isSupportedToBuildEffective()} returns {@code false}, this method's behaviour is undefined.
116      *
117      * @return Effective statement instance.
118      */
119     @NonNull E buildEffective();
120
121     boolean isSupportedToBuildEffective();
122
123     boolean isSupportedByFeatures();
124
125     Collection<? extends StmtContext<?, ?, ?>> getEffectOfStatement();
126
127     /*
128      * FIXME: YANGTOOLS-784: the next three methods are closely related to the copy process:
129      *        - copyHistory() is a brief summary of what went on
130      *        - getOriginalContext() points to the CopyHistory.ORIGINAL
131      *        - getPreviousCopyCtx() points to the immediate predecessor forming a singly-linked list terminated
132      *          at getOriginalContext()
133      *
134      *        When implementing YANGTOOLS-784, this needs to be taken into account and properly forwarded through
135      *        intermediate MutableTrees. Also note this closely relates to current namespace context, as taken into
136      *        account when creating the argument. At least parts of this are only needed during buildEffective()
137      *        and hence should become arguments to that method.
138      */
139
140     /**
141      * Return the statement context of the original definition, if this statement is an instantiated copy.
142      *
143      * @return Original definition, if this statement was copied.
144      */
145     Optional<StmtContext<A, D, E>> getOriginalCtx();
146
147     /**
148      * Return the context of the previous copy of this statement -- effectively walking towards the source origin
149      * of this statement.
150      *
151      * @return Context of the previous copy of this statement, if this statement has been copied.
152      */
153     Optional<StmtContext<A, D, E>> getPreviousCopyCtx();
154
155     /**
156      * Create a replica of this statement as a substatement of specified {@code parent}. The replica must not be
157      * modified and acts as a source of {@link EffectiveStatement} from outside of {@code parent}'s subtree.
158      *
159      * @param parent Parent of the replica statement
160      * @return replica of this statement
161      * @throws IllegalArgumentException if this statement cannot be replicated into parent, for example because it
162      *                                  comes from an alien implementation.
163      */
164     @NonNull Mutable<A, D, E> replicaAsChildOf(Mutable<?, ?, ?> parent);
165
166     @Beta
167     @NonNull Optional<? extends Mutable<?, ?, ?>> copyAsChildOf(Mutable<?, ?, ?> parent, CopyType type,
168             @Nullable QNameModule targetModule);
169
170     ModelProcessingPhase getCompletedPhase();
171
172     /**
173      * An mutable view of an inference context associated with an instance of a statement.
174      *
175      * @param <A> Argument type
176      * @param <D> Declared Statement representation
177      * @param <E> Effective Statement representation
178      */
179     interface Mutable<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
180             extends StmtContext<A, D, E> {
181
182         @Override
183         Mutable<?, ?, ?> getParentContext();
184
185         @Override
186         default Mutable<?, ?, ?> coerceParentContext() {
187             return verifyNotNull(getParentContext(), "Root context %s does not have a parent", this);
188         }
189
190         /**
191          * Associate a value with a key within a namespace.
192          *
193          * @param type Namespace type
194          * @param key Key
195          * @param value value
196          * @param <K> namespace key type
197          * @param <V> namespace value type
198          * @param <N> namespace type
199          * @param <T> key type
200          * @param <U> value type
201          * @throws NamespaceNotAvailableException when the namespace is not available.
202          */
203         <K, V, T extends K, U extends V, N extends ParserNamespace<K, V>> void addToNs(Class<@NonNull N> type,
204                 T key, U value);
205
206         @Override
207         RootStmtContext.Mutable<?, ?, ?> getRoot();
208
209         /**
210          * Create a child sub-statement, which is a child of this statement, inheriting all attributes from specified
211          * child and recording copy type. Resulting object may only be added as a child of this statement.
212          *
213          * @param stmt Statement to be used as a template
214          * @param type Type of copy to record in history
215          * @param targetModule Optional new target module
216          * @return copy of statement considering {@link CopyType} (augment, uses)
217          *
218          * @throws IllegalArgumentException if stmt cannot be copied into this statement, for example because it comes
219          *                                  from an alien implementation.
220          * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException
221          */
222         Mutable<?, ?, ?> childCopyOf(StmtContext<?, ?, ?> stmt, CopyType type, @Nullable QNameModule targetModule);
223
224         /**
225          * Create a child sub-statement, which is a child of this statement, inheriting all attributes from specified
226          * child and recording copy type. Resulting object may only be added as a child of this statement.
227          *
228          * @param stmt Statement to be used as a template
229          * @param type Type of copy to record in history
230          * @return copy of statement considering {@link CopyType} (augment, uses)
231          *
232          * @throws IllegalArgumentException if stmt cannot be copied into this statement, for example because it comes
233          *                                  from an alien implementation.
234          * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException
235          */
236         default Mutable<?, ?, ?> childCopyOf(final StmtContext<?, ?, ?> stmt, final CopyType type) {
237             return childCopyOf(stmt, type, null);
238         }
239
240         @Override
241         default Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
242             return mutableDeclaredSubstatements();
243         }
244
245         @NonNull Collection<? extends Mutable<?, ?, ?>> mutableDeclaredSubstatements();
246
247         @Override
248         default Collection<? extends StmtContext<?, ?, ?>> effectiveSubstatements() {
249             return mutableEffectiveSubstatements();
250         }
251
252         @NonNull Collection<? extends Mutable<?, ?, ?>> mutableEffectiveSubstatements();
253
254         /**
255          * Create a new inference action to be executed during specified phase. The action cannot be cancelled
256          * and will be executed even if its definition remains incomplete. The specified phase cannot complete until
257          * this action is resolved. If the action cannot be resolved, model processing will fail.
258          *
259          * @param phase Target phase in which the action will resolved.
260          * @return A new action builder.
261          * @throws NullPointerException if the specified phase is null
262          */
263         @NonNull ModelActionBuilder newInferenceAction(@NonNull ModelProcessingPhase phase);
264
265         /**
266          * Adds s statement to namespace map with a key.
267          *
268          * @param namespace
269          *            {@link StatementNamespace} child that determines namespace to be added to
270          * @param key
271          *            of type according to namespace class specification
272          * @param stmt
273          *            to be added to namespace map
274          */
275         <K, KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(Class<@NonNull N> namespace, KT key,
276                 StmtContext<?, ?, ?> stmt);
277
278         /**
279          * Set version of root statement context.
280          *
281          * @param version
282          *            of root statement context
283          */
284         void setRootVersion(YangVersion version);
285
286         /**
287          * Add required module. Based on these dependencies are collected required sources from library sources.
288          *
289          * @param dependency
290          *            SourceIdentifier of module required by current root
291          *            context
292          */
293         /*
294          * FIXME: this method is used solely during SOURCE_PRE_LINKAGE reactor phase and does not have a corresponding
295          *        getter -- which makes it rather strange. At some point this method needs to be deprecated and its
296          *        users migrated to use proper global namespace.
297          */
298         void addRequiredSource(SourceIdentifier dependency);
299
300         /**
301          * Adds an effective statement to collection of substatements.
302          *
303          * @param substatement substatement
304          * @throws IllegalStateException if added in declared phase
305          * @throws NullPointerException if {@code substatement} is null
306          */
307         void addEffectiveSubstatement(Mutable<?, ?, ?> substatement);
308
309         /**
310          * Adds an effective statement to collection of substatements.
311          *
312          * @param statements substatements
313          * @throws IllegalStateException if added in declared phase
314          * @throws NullPointerException if statement parameter is null
315          */
316         void addEffectiveSubstatements(Collection<? extends Mutable<?, ?, ?>> statements);
317
318         /**
319          * Adds a purely-effective statement to collection of substatements. The statement will report a {@code null}
320          * {@link EffectiveStatement#getDeclared()} object. A typical example of statements which require this mechanics
321          * are {@code rpc} and {@code action} statements, which always have {@code input} and {@code output}
322          * substatements, even if those are not declared in YANG text.
323          *
324          * @param support Statement support of the statement being created
325          * @param arg Effective argument. If specified as {@code null}, statement support will be consulted for the
326          *            empty argument.
327          * @throws IllegalArgumentException if {@code support} does not implement {@link UndeclaredStatementFactory}
328          * @throws IllegalStateException if added in declared phase
329          * @throws NullPointerException if {@code support} is null
330          */
331         @Beta
332         <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
333             @NonNull Mutable<X, Y, Z> addUndeclaredSubstatement(StatementSupport<X, Y, Z> support, @Nullable X arg);
334
335         @Beta
336         void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef);
337
338         /**
339          * Removes a statement context from the effective substatements based on its statement definition (i.e statement
340          * keyword) and raw (in String form) statement argument. The statement context is removed only if both statement
341          * definition and statement argument match with one of the effective substatements' statement definition
342          * and argument.
343          *
344          * <p>
345          * If the statementArg parameter is null, the statement context is removed based only on its statement
346          * definition.
347          *
348          * @param statementDef statement definition of the statement context to remove
349          * @param statementArg statement argument of the statement context to remove
350          */
351         @Beta
352         void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef, String statementArg);
353
354         @Beta
355         // FIXME: this information should be exposed as a well-known Namespace
356         boolean hasImplicitParentSupport();
357
358         @Beta
359         StmtContext<?, ?, ?> wrapWithImplicit(StmtContext<?, ?, ?> original);
360
361         void addAsEffectOfStatement(Collection<? extends StmtContext<?, ?, ?>> ctxs);
362
363         /**
364          * Set identifier of current root context.
365          *
366          * @param identifier
367          *            of current root context, must not be null
368          */
369         void setRootIdentifier(SourceIdentifier identifier);
370
371         void setUnsupported();
372     }
373 }