Refactor InferenceAction
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / ModifierImpl.java
index c0c3fcf3ef67c64e55dea6398fbb69517a94eef7..e917f958ef65a026d840982fc7866999e79e551d 100644 (file)
@@ -17,6 +17,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 import java.util.function.Function;
+import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
@@ -33,20 +34,17 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase.
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-class ModifierImpl implements ModelActionBuilder {
+final class ModifierImpl implements ModelActionBuilder {
     private static final Logger LOG = LoggerFactory.getLogger(ModifierImpl.class);
 
+    private final InferenceContext ctx = new InferenceContext() { };
+
     private final Set<AbstractPrerequisite<?>> unsatisfied = new HashSet<>(1);
     private final Set<AbstractPrerequisite<?>> mutations = new HashSet<>(1);
-    private final ModelProcessingPhase phase;
 
     private InferenceAction action;
     private boolean actionApplied = false;
 
-    ModifierImpl(final ModelProcessingPhase phase) {
-        this.phase = Preconditions.checkNotNull(phase);
-    }
-
     private <D> AbstractPrerequisite<D> addReq(final AbstractPrerequisite<D> prereq) {
         LOG.trace("Modifier {} adding prerequisite {}", this, prereq);
         unsatisfied.add(prereq);
@@ -80,10 +78,6 @@ class ModifierImpl implements ModelActionBuilder {
         return unsatisfied.isEmpty();
     }
 
-    ModelProcessingPhase getPhase() {
-        return phase;
-    }
-
     boolean isApplied() {
         return actionApplied;
     }
@@ -96,29 +90,34 @@ class ModifierImpl implements ModelActionBuilder {
 
     private void applyAction() {
         Preconditions.checkState(!actionApplied);
-        action.apply();
+        action.apply(ctx);
         actionApplied = true;
     }
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
-    private <K, C extends StmtContext<?,?,?>, N extends StatementNamespace<K, ?, ?>> AbstractPrerequisite<C> requiresCtxImpl(final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key,final ModelProcessingPhase phase)  {
+    private <K, C extends StmtContext<?,?,?>, N extends StatementNamespace<K, ?, ?>> AbstractPrerequisite<C>
+            requiresCtxImpl(final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key,
+                    final ModelProcessingPhase phase)  {
         checkNotRegistered();
+
         try {
             AddedToNamespace<C> addedToNs = new AddedToNamespace<>(phase);
             addReq(addedToNs);
-            contextImpl(context).onNamespaceItemAddedAction((Class) namespace,key,addedToNs);
+            contextImpl(context).onNamespaceItemAddedAction((Class) namespace, key, addedToNs);
             return addedToNs;
         } catch (SourceException e) {
             throw shouldNotHappenProbablyBug(e);
         }
     }
 
-    private <C extends StmtContext<?, ?, ?>> AbstractPrerequisite<C> requiresCtxImpl(final C context, final ModelProcessingPhase phase) {
-        Preconditions.checkState(action == null, "Action was already registered.");
+    private <C extends StmtContext<?, ?, ?>> AbstractPrerequisite<C> requiresCtxImpl(final C context,
+            final ModelProcessingPhase phase) {
+        checkNotRegistered();
+
         try {
             PhaseFinished<C> phaseFin = new PhaseFinished<>();
             addReq(phaseFin);
-            contextImpl(context).addPhaseCompletedListener(phase,phaseFin);
+            contextImpl(context).addPhaseCompletedListener(phase, phaseFin);
             return phaseFin;
         } catch (SourceException e) {
             throw shouldNotHappenProbablyBug(e);
@@ -126,18 +125,21 @@ class ModifierImpl implements ModelActionBuilder {
     }
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
-    private <K, C extends StmtContext.Mutable<?, ?, ?> , N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>> AbstractPrerequisite<C> mutatesCtxImpl(
-                final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key, final ModelProcessingPhase phase) {
-            try {
-                PhaseModificationInNamespace<C> mod = new PhaseModificationInNamespace<>(phase);
-                addReq(mod);
-                addMutation(mod);
-                contextImpl(context).onNamespaceItemAddedAction((Class) namespace,key,mod);
-                return mod;
-            } catch (SourceException e) {
-                throw shouldNotHappenProbablyBug(e);
-            }
+    private <K, C extends StmtContext.Mutable<?, ?, ?> , N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
+            AbstractPrerequisite<C> mutatesCtxImpl(final StmtContext<?, ?, ?> context, final Class<N> namespace,
+                    final K key, final ModelProcessingPhase phase) {
+        checkNotRegistered();
+
+        try {
+            PhaseModificationInNamespace<C> mod = new PhaseModificationInNamespace<>(phase);
+            addReq(mod);
+            addMutation(mod);
+            contextImpl(context).onNamespaceItemAddedAction((Class) namespace, key, mod);
+            return mod;
+        } catch (SourceException e) {
+            throw shouldNotHappenProbablyBug(e);
         }
+    }
 
     private static StatementContextBase<?,?,?> contextImpl(final Object value) {
         Preconditions.checkArgument(value instanceof StatementContextBase,"Supplied context was not provided by this reactor.");
@@ -154,6 +156,7 @@ class ModifierImpl implements ModelActionBuilder {
         return false;
     }
 
+    @Nonnull
     @Override
     public <C extends Mutable<?, ?, ?>, CT extends C> Prerequisite<C> mutatesCtx(final CT context, final ModelProcessingPhase phase) {
         try {
@@ -163,46 +166,54 @@ class ModifierImpl implements ModelActionBuilder {
         }
     }
 
+    @Nonnull
     @Override
     public <A,D extends DeclaredStatement<A>,E extends EffectiveStatement<A, D>> AbstractPrerequisite<StmtContext<A, D, E>> requiresCtx(final StmtContext<A, D, E> context, final ModelProcessingPhase phase) {
         return requiresCtxImpl(context, phase);
     }
 
 
+    @Nonnull
     @Override
     public <K, N extends StatementNamespace<K, ?, ? >> Prerequisite<StmtContext<?,?,?>> requiresCtx(final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key, final ModelProcessingPhase phase) {
         return requiresCtxImpl(context, namespace, key, phase);
     }
 
+    @Nonnull
     @Override
     public <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(final StmtContext<?, ? extends D, ?> context) {
         return requiresCtxImpl(context, FULL_DECLARATION).transform(StmtContext::buildDeclared);
     }
 
+    @Nonnull
     @Override
     public <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>> AbstractPrerequisite<StmtContext<?, D, ?>> requiresDeclaredCtx(
             final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key) {
         return requiresCtxImpl(context, namespace, key, FULL_DECLARATION);
     }
 
+    @Nonnull
     @Override
     public <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>> Prerequisite<D> requiresDeclared(
             final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key) {
-        final AbstractPrerequisite<StmtContext<?,D,?>> rawContext = requiresCtxImpl(context, namespace, key, FULL_DECLARATION);
+        final AbstractPrerequisite<StmtContext<?, D, ?>> rawContext = requiresCtxImpl(context, namespace, key, FULL_DECLARATION);
         return rawContext.transform(StmtContext::buildDeclared);
     }
 
+    @Nonnull
     @Override
     public <E extends EffectiveStatement<?, ?>> Prerequisite<E> requiresEffective(final StmtContext<?, ?, ? extends E> stmt) {
         return requiresCtxImpl(stmt, EFFECTIVE_MODEL).transform(StmtContext::buildEffective);
     }
 
+    @Nonnull
     @Override
     public <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>> AbstractPrerequisite<StmtContext<?, ?, E>> requiresEffectiveCtx(
             final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key) {
-        return requiresCtxImpl(contextImpl(context), namespace,key, EFFECTIVE_MODEL);
+        return requiresCtxImpl(contextImpl(context), namespace, key, EFFECTIVE_MODEL);
     }
 
+    @Nonnull
     @Override
     public <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>> Prerequisite<E> requiresEffective(
             final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key) {
@@ -211,6 +222,7 @@ class ModifierImpl implements ModelActionBuilder {
     }
 
 
+    @Nonnull
     @Override
     public <N extends IdentifierNamespace<?, ?>> Prerequisite<Mutable<?, ?, ?>> mutatesNs(final Mutable<?, ?, ?> context,
             final Class<N> namespace) {
@@ -221,12 +233,8 @@ class ModifierImpl implements ModelActionBuilder {
         }
     }
 
+    @Nonnull
     @Override
-    public <T extends Mutable<?, ?, ?>> Prerequisite<T> mutatesEffectiveCtx(final T stmt) {
-        return mutatesCtx(stmt, EFFECTIVE_MODEL);
-    }
-
-   @Override
     public <K, E extends EffectiveStatement<?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>> AbstractPrerequisite<Mutable<?, ?, E>> mutatesEffectiveCtx(
             final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key) {
         return mutatesCtxImpl(context, namespace, key, EFFECTIVE_MODEL);
@@ -244,13 +252,13 @@ class ModifierImpl implements ModelActionBuilder {
         private T value;
 
         @Override
-        public final T get() {
-            Preconditions.checkState(isDone());
+        public final T resolve(final InferenceContext ctx) {
+            Preconditions.checkState(done);
+            Preconditions.checkArgument(ctx == ModifierImpl.this.ctx);
             return value;
         }
 
-        @Override
-        public final boolean isDone() {
+        final boolean isDone() {
             return done;
         }
 
@@ -260,18 +268,8 @@ class ModifierImpl implements ModelActionBuilder {
             return isApplied();
         }
 
-        final <O> Prerequisite<O> transform(final Function<? super T,O> transformation) {
-            return new Prerequisite<O>() {
-                @Override
-                public O get() {
-                    return transformation.apply(AbstractPrerequisite.this.get());
-                }
-
-                @Override
-                public boolean isDone() {
-                    return AbstractPrerequisite.this.isDone();
-                }
-            };
+        final <O> Prerequisite<O> transform(final Function<? super T, O> transformation) {
+            return ctx -> transformation.apply(resolve(ctx));
         }
 
         @Override
@@ -301,17 +299,17 @@ class ModifierImpl implements ModelActionBuilder {
         @SuppressWarnings("unchecked")
         @Override
         public boolean phaseFinished(final StatementContextBase<?, ?, ?> context, final ModelProcessingPhase phase) {
-            return resolvePrereq((C) (context));
+            return resolvePrereq((C) context);
         }
     }
 
-    private class NamespaceMutation<N extends IdentifierNamespace<?,?>> extends  AbstractPrerequisite<StmtContext.Mutable<?, ?, ?>>  {
+    private class NamespaceMutation<N extends IdentifierNamespace<?,?>> extends AbstractPrerequisite<StmtContext.Mutable<?, ?, ?>>  {
         public NamespaceMutation(final StatementContextBase<?, ?, ?> ctx, final Class<N> namespace) {
             resolvePrereq(ctx);
         }
     }
 
-    private class AddedToNamespace<C extends StmtContext<?,?,?>> extends  AbstractPrerequisite<C> implements OnNamespaceItemAdded,OnPhaseFinished {
+    private class AddedToNamespace<C extends StmtContext<?,?,?>> extends AbstractPrerequisite<C> implements OnNamespaceItemAdded,OnPhaseFinished {
         private final ModelProcessingPhase phase;
 
         public <K, N extends StatementNamespace<K, ?, ?>> AddedToNamespace(final ModelProcessingPhase phase) {