Rework identifier path subscription
[yangtools.git] / yang / yang-parser-spi / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / ModelActionBuilder.java
index 1693b73c05813a596c0eb1e5193770d8194281a6..b50b00924fc0e90e52760c70485109ef78dbc9eb 100644 (file)
@@ -16,36 +16,30 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
 
-
 /**
- * Builder for effective model inference action.
- *
- * Model inference action is core principle of transforming
+ * Builder for effective model inference action. Model inference action is core principle of transforming
  * declared model into effective model.
  *
- * Since YANG allows forward references, some inference actions
- * need to be taken at a later point, where reference is actually
- * resolved. Referenced objects are not retrieved directly
- * but are represented as {@link Prerequisite} (prerequisite) for
- * inference action to be taken.
+ * <p>
+ * Since YANG allows forward references, some inference actions need to be taken at a later point, where reference is
+ * actually resolved. Referenced objects are not retrieved directly but are represented as {@link Prerequisite}
+ * (prerequisite) for inference action to be taken.
  *
- * Some existing YANG statements are more complex and also object,
- * for which effective model may be inferred is also represented
- * as {@link Prerequisite} which once, when reference is available
- * will contain target context, which may be used for inference
- * action.
+ * <p>
+ * Some existing YANG statements are more complex and also object, for which effective model may be inferred is also
+ * represented as a {@link Prerequisite} which, when reference is available, will contain target context, which may be
+ * used for inference action.
  *
  * <h2>Implementing inference action</h2>
- *
- * Effective inference action could always be splitted into two
- * separate tasks:
+ * Effective inference action could always be splitted into two separate tasks:
  * <ol>
  * <li>Declaration of inference action and its prerequisites</li>
  * <li>Execution of inference action</li>
  * </ol>
+ *
+ * <p>
  * In order to declare inference action following steps needs
  * to be taken:
- *
  * <ol>
  * <li>Use {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)} to obtain
  * {@link ModelActionBuilder}.
@@ -57,7 +51,8 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
  * to register inference action.
  * </ol>
  *
- * Action will be executed when:
+ * <p>
+ * An action will be executed when:
  * <ul>
  * <li> {@link InferenceAction#apply(InferenceContext)} - all prerequisites (and declared forward references) are met,
  * action could dereference them and start applying changes.
@@ -67,19 +62,17 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
  * </li>
  * </ul>
  *
+ * <p>
  * TODO: Insert real word example
  *
  * <h2>Design notes</h2>
- * {@link java.util.concurrent.Future} seems as viable and more standard
- * alternative to {@link Prerequisite}, but futures also carries
- * promise that resolution of it is carried in other
- * thread, which will actually put additional constraints on
- * semantic parser.
+ * {@link java.util.concurrent.Future} seems as viable and more standard alternative to {@link Prerequisite}, but
+ * Futures also carries promise that resolution of it is carried in other thread, which will actually put additional
+ * constraints on semantic parser.
  *
- * Also listening on multiple futures is costly, so we opted
- * out of future and designed API, which later may introduce
+ * <p>
+ * Also listening on multiple futures is costly, so we opted out of future and designed API, which later may introduce
  * futures.
- *
  */
 public interface ModelActionBuilder {
     interface InferenceContext {
@@ -103,34 +96,32 @@ public interface ModelActionBuilder {
     interface InferenceAction {
 
         /**
-         * Invoked once all prerequisites were met and forward references
-         * were resolved and inference action should be applied.
-         *
-         * Implementors may do necessary changes to mutable objects
-         * which were declared.
+         * Invoked once all prerequisites were met and forward references were resolved and inference action should be
+         * applied. Implementors may perform necessary changes to mutable objects which were declared.
          *
-         * @throws InferenceException If inference action can not be processed.
-         *      Note that this exception be used for user to debug YANG sources,
-         *      so should provide helpful context to fix issue in sources.
+         * @throws InferenceException If inference action can not be processed. Note that this exception be used for
+         *         user to debug YANG sources, so should provide helpful context to fix issue in sources.
          */
-        void apply(InferenceContext ctx) throws InferenceException;
+        void apply(InferenceContext ctx);
 
         /**
-         * Invoked once one of prerequisites was not met,
-         * even after all other satisfiable inference actions were processed.
+         * Invoked once one of prerequisites was not met, even after all other satisfiable inference actions were
+         * processed.
          *
-         * Implementors MUST throw {@link InferenceException} if semantic processing
-         * of model should be stopped and failed.
+         * <p>
+         * Implementors MUST throw {@link InferenceException} if semantic processing of model should be stopped
+         * and failed.
          *
-         * List of failed prerequisites should be used to select right message / error
-         * type to debug problem in YANG sources.
+         * <p>
+         * List of failed prerequisites should be used to select right message / error type to debug problem in YANG
+         * sources.
          *
          * @param failed collection of prerequisites which were not met
-         * @throws InferenceException If inference action can not be processed.
-         *      Note that this exception be used for user to debug YANG sources,
-         *      so should provide helpful context to fix issue in sources.
+         * @throws InferenceException If inference action can not be processed. Note that this exception be used
+         *                            by user to debug YANG sources, hence it should provide helpful context to fix
+         *                            the issue in sources.
          */
-        void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException;
+        void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed);
     }
 
     /**
@@ -143,7 +134,17 @@ public interface ModelActionBuilder {
     @Nonnull <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(StmtContext<?, ? extends D, ?> context);
 
     /**
-     * Action requires that the specified context completes specified phase.
+     * Create a requirement on specified statement to be declared.
+     *
+     * @deprecated Undocumented method. Use at your own risk.
+     */
+    @Deprecated
+    @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
+        Prerequisite<D> requiresDeclared(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
+
+    /**
+     * Action requires that the specified context completes specified phase before {@link #apply(InferenceAction)}
+     * may be invoked.
      *
      * @param context Statement context which needs to complete the transition.
      * @param phase ModelProcessingPhase which must have completed
@@ -152,29 +153,57 @@ public interface ModelActionBuilder {
     @Nonnull <A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
         Prerequisite<StmtContext<A, D, E>> requiresCtx(StmtContext<A, D, E> context, ModelProcessingPhase phase);
 
-    @Nonnull <K, N extends StatementNamespace<K, ?, ? >> Prerequisite<StmtContext<?,?,?>> requiresCtx(
+    @Nonnull <K, N extends StatementNamespace<K, ?, ?>> Prerequisite<StmtContext<?, ?, ?>> requiresCtx(
         StmtContext<?, ?, ?> context, Class<N> namespace, K key, ModelProcessingPhase phase);
 
-    default @Nonnull <T extends Mutable<?, ?, ?>> Prerequisite<T> mutatesEffectiveCtx(final T stmt) {
-        return mutatesCtx(stmt, EFFECTIVE_MODEL);
+    @Nonnull <K, N extends StatementNamespace<K, ?, ?>> Prerequisite<StmtContext<?, ?, ?>> requiresCtx(
+            StmtContext<?, ?, ?> context, Class<N> namespace, NamespaceKeyCriterion<K> criterion,
+            ModelProcessingPhase phase);
+
+    /**
+     * Action mutates the effective model of specified statement. This is a shorthand for
+     * {@code mutatesCtx(context, EFFECTIVE_MODEL}.
+     *
+     * @param context Target statement context
+     * @return A {@link Prerequisite} returning the requested context.
+     */
+    default @Nonnull <T extends Mutable<?, ?, ?>> Prerequisite<T> mutatesEffectiveCtx(final T context) {
+        return mutatesCtx(context, EFFECTIVE_MODEL);
     }
 
     @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
         Prerequisite<Mutable<?, ?, E>> mutatesEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
 
-    @Nonnull <C extends StmtContext.Mutable<?, ?, ?>, CT extends C> Prerequisite<C> mutatesCtx(CT root,
-            ModelProcessingPhase phase);
+    default @Nonnull <K, E extends EffectiveStatement<?, ?>,
+            N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>> Prerequisite<Mutable<?, ?, E>>
+                mutatesEffectiveCtxPath(final StmtContext<?, ?, ?> context, final Class<N> namespace,
+                        final Iterable<K> keys) {
+        throw new UnsupportedOperationException(getClass() + " does not implement mutatesEffectiveCtxPath()");
+    }
 
-    void apply(InferenceAction action) throws InferenceException;
+    /**
+     * Action mutates the specified statement in the specified phase. Target statement cannot complete specified
+     * phase before this action is applier.
+     *
+     * @param context Target statement context
+     * @return A {@link Prerequisite} returning the requested context.
+     */
+    @Nonnull <C extends Mutable<?, ?, ?>, T extends C> Prerequisite<C> mutatesCtx(T context,
+            ModelProcessingPhase phase);
 
     /**
-     * @deprecated Undocumented method. Use at your own risk.
+     * Apply an {@link InferenceAction} when this action's prerequisites are resolved.
+     *
+     * @param action Inference action to apply
+     * @throws InferenceException if the action fails
+     * @throws NullPointerException if {@code action is null}
+     * @throws IllegalStateException if this action has an inference action already associated.
      */
-    @Deprecated
-    @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>>
-        Prerequisite<D> requiresDeclared(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
+    void apply(InferenceAction action);
 
     /**
+     * Create a requirement on specified statement context to be declared.
+     *
      * @deprecated Undocumented method. Use at your own risk.
      */
     @Deprecated
@@ -182,6 +211,8 @@ public interface ModelActionBuilder {
         Prerequisite<StmtContext<?, D, ?>> requiresDeclaredCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
 
     /**
+     * Create a requirement on specified statement to become effective.
+     *
      * @deprecated Undocumented method. Use at your own risk.
      */
     @Deprecated
@@ -189,6 +220,8 @@ public interface ModelActionBuilder {
             StmtContext<?, ?, ? extends E> stmt);
 
     /**
+     * Create a requirement on specified statement to become effective.
+     *
      * @deprecated Undocumented method. Use at your own risk.
      */
     @Deprecated
@@ -196,6 +229,8 @@ public interface ModelActionBuilder {
         Prerequisite<E> requiresEffective(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
 
     /**
+     * Create a requirement on specified statement context to become effective.
+     *
      * @deprecated Undocumented method. Use at your own risk.
      */
     @Deprecated
@@ -204,6 +239,8 @@ public interface ModelActionBuilder {
             K key);
 
     /**
+     * Mark the fact that this action is mutating a namespace.
+     *
      * @deprecated Undocumented method. Use at your own risk.
      */
     @Deprecated