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 com.google.common.base.Verify.verifyNotNull;
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;
30 * An inference context associated with an instance of a statement.
32 * @param <A> Argument type
33 * @param <D> Declared Statement representation
34 * @param <E> Effective Statement representation
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() {
44 * Return the parent statement context, or null if this is the root statement.
46 * @return context of parent of statement, or null if this is the root statement.
48 @Nullable StmtContext<?, ?, ?> getParentContext();
51 * Return the parent statement context, forcing a VerifyException if this is the root statement.
53 * @return context of parent of statement
54 * @throws VerifyException if this statement is the root statement
56 default @NonNull StmtContext<?, ?, ?> coerceParentContext() {
57 return verifyNotNull(getParentContext(), "Root context %s does not have a parent", this);
61 * Returns the model root for this statement.
63 * @return root context of statement
65 @NonNull RootStmtContext<?, ?, ?> getRoot();
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:
77 * reports the same structure as the canonical verbose equivalent:
87 * Returned collection is therefore well suited for reasoning about the schema tree. It is not appropriate for
88 * populating populating {@link DeclaredStatement#declaredSubstatements()}.
90 * @return Collection of declared substatements
92 @NonNull Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements();
95 * Return effective substatements. These are the statements which are added as this statement's substatements
96 * complete their effective model phase.
98 * @return Collection of declared substatements
100 @NonNull Collection<? extends StmtContext<?, ?, ?>> effectiveSubstatements();
102 default Iterable<? extends StmtContext<?, ?, ?>> allSubstatements() {
103 return Iterables.concat(declaredSubstatements(), effectiveSubstatements());
106 default Stream<? extends StmtContext<?, ?, ?>> allSubstatementsStream() {
107 return Streams.concat(declaredSubstatements().stream(), effectiveSubstatements().stream());
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.
115 * If {@link #isSupportedToBuildEffective()} returns {@code false}, this method's behaviour is undefined.
117 * @return Effective statement instance.
119 @NonNull E buildEffective();
121 boolean isSupportedToBuildEffective();
123 boolean isSupportedByFeatures();
125 Collection<? extends StmtContext<?, ?, ?>> getEffectOfStatement();
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()
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.
141 * Return the statement context of the original definition, if this statement is an instantiated copy.
143 * @return Original definition, if this statement was copied.
145 Optional<StmtContext<A, D, E>> getOriginalCtx();
148 * Return the context of the previous copy of this statement -- effectively walking towards the source origin
151 * @return Context of the previous copy of this statement, if this statement has been copied.
153 Optional<StmtContext<A, D, E>> getPreviousCopyCtx();
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.
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.
164 @NonNull Mutable<A, D, E> replicaAsChildOf(Mutable<?, ?, ?> parent);
167 @NonNull Optional<? extends Mutable<?, ?, ?>> copyAsChildOf(Mutable<?, ?, ?> parent, CopyType type,
168 @Nullable QNameModule targetModule);
170 ModelProcessingPhase getCompletedPhase();
173 * An mutable view of an inference context associated with an instance of a statement.
175 * @param <A> Argument type
176 * @param <D> Declared Statement representation
177 * @param <E> Effective Statement representation
179 interface Mutable<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
180 extends StmtContext<A, D, E> {
183 Mutable<?, ?, ?> getParentContext();
186 default Mutable<?, ?, ?> coerceParentContext() {
187 return verifyNotNull(getParentContext(), "Root context %s does not have a parent", this);
191 * Associate a value with a key within a namespace.
193 * @param type Namespace type
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.
203 <K, V, T extends K, U extends V, N extends ParserNamespace<K, V>> void addToNs(Class<@NonNull N> type,
207 RootStmtContext.Mutable<?, ?, ?> getRoot();
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.
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)
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
222 Mutable<?, ?, ?> childCopyOf(StmtContext<?, ?, ?> stmt, CopyType type, @Nullable QNameModule targetModule);
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.
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)
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
236 default Mutable<?, ?, ?> childCopyOf(final StmtContext<?, ?, ?> stmt, final CopyType type) {
237 return childCopyOf(stmt, type, null);
241 default Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
242 return mutableDeclaredSubstatements();
245 @NonNull Collection<? extends Mutable<?, ?, ?>> mutableDeclaredSubstatements();
248 default Collection<? extends StmtContext<?, ?, ?>> effectiveSubstatements() {
249 return mutableEffectiveSubstatements();
252 @NonNull Collection<? extends Mutable<?, ?, ?>> mutableEffectiveSubstatements();
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.
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
263 @NonNull ModelActionBuilder newInferenceAction(@NonNull ModelProcessingPhase phase);
266 * Adds s statement to namespace map with a key.
269 * {@link StatementNamespace} child that determines namespace to be added to
271 * of type according to namespace class specification
273 * to be added to namespace map
275 <K, KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(Class<@NonNull N> namespace, KT key,
276 StmtContext<?, ?, ?> stmt);
279 * Set version of root statement context.
282 * of root statement context
284 void setRootVersion(YangVersion version);
287 * Add required module. Based on these dependencies are collected required sources from library sources.
290 * SourceIdentifier of module required by current root
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.
298 void addRequiredSource(SourceIdentifier dependency);
301 * Adds an effective statement to collection of substatements.
303 * @param substatement substatement
304 * @throws IllegalStateException if added in declared phase
305 * @throws NullPointerException if {@code substatement} is null
307 void addEffectiveSubstatement(Mutable<?, ?, ?> substatement);
310 * Adds an effective statement to collection of substatements.
312 * @param statements substatements
313 * @throws IllegalStateException if added in declared phase
314 * @throws NullPointerException if statement parameter is null
316 void addEffectiveSubstatements(Collection<? extends Mutable<?, ?, ?>> statements);
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.
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
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
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);
336 void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef);
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
345 * If the statementArg parameter is null, the statement context is removed based only on its statement
348 * @param statementDef statement definition of the statement context to remove
349 * @param statementArg statement argument of the statement context to remove
352 void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef, String statementArg);
355 // FIXME: this information should be exposed as a well-known Namespace
356 boolean hasImplicitParentSupport();
359 StmtContext<?, ?, ?> wrapWithImplicit(StmtContext<?, ?, ?> original);
361 void addAsEffectOfStatement(Collection<? extends StmtContext<?, ?, ?>> ctxs);
364 * Set identifier of current root context.
367 * of current root context, must not be null
369 void setRootIdentifier(SourceIdentifier identifier);
371 void setUnsupported();