Populate parser/ hierarchy
[yangtools.git] / yang / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / ModifierImpl.java
diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java
deleted file mode 100644 (file)
index d8e7431..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (c) 2015, 2016 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.stmt.reactor;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.base.Verify.verifyNotNull;
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.EFFECTIVE_MODEL;
-import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.FULL_DECLARATION;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.function.Function;
-import org.eclipse.jdt.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.parser.spi.meta.ModelActionBuilder;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase.ContextMutation;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase.OnNamespaceItemAdded;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase.OnPhaseFinished;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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 InferenceAction action;
-    private boolean actionApplied = false;
-
-    private <D> AbstractPrerequisite<D> addReq(final AbstractPrerequisite<D> prereq) {
-        LOG.trace("Modifier {} adding prerequisite {}", this, prereq);
-        unsatisfied.add(prereq);
-        return prereq;
-    }
-
-    private <T> @NonNull AbstractPrerequisite<T> addMutation(final @NonNull AbstractPrerequisite<T> mutation) {
-        LOG.trace("Modifier {} adding mutation {}", this, mutation);
-        mutations.add(mutation);
-        return mutation;
-    }
-
-    private void checkNotRegistered() {
-        checkState(action == null, "Action was already registered.");
-    }
-
-    private boolean removeSatisfied() {
-        final Iterator<AbstractPrerequisite<?>> it = unsatisfied.iterator();
-        while (it.hasNext()) {
-            final AbstractPrerequisite<?> prereq = it.next();
-            if (prereq.isDone()) {
-                // We are removing current prerequisite from list.
-                LOG.trace("Modifier {} prerequisite {} satisfied", this, prereq);
-                it.remove();
-            }
-        }
-        return unsatisfied.isEmpty();
-    }
-
-    boolean isApplied() {
-        return actionApplied;
-    }
-
-    void failModifier() {
-        removeSatisfied();
-        action.prerequisiteFailed(unsatisfied);
-        action = null;
-    }
-
-    private <K, C extends StmtContext<?, ?, ?>, N extends StatementNamespace<K, ?, ?>> @NonNull AbstractPrerequisite<C>
-            requiresCtxImpl(final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key,
-                    final ModelProcessingPhase phase)  {
-        checkNotRegistered();
-
-        AddedToNamespace<C> addedToNs = new AddedToNamespace<>(phase);
-        addReq(addedToNs);
-        contextImpl(context).onNamespaceItemAddedAction(namespace, key, addedToNs);
-        return addedToNs;
-    }
-
-    private <K, C extends StmtContext<?, ?, ?>, N extends StatementNamespace<K, ?, ?>> @NonNull AbstractPrerequisite<C>
-            requiresCtxImpl(final StmtContext<?, ?, ?> context, final Class<N> namespace,
-                    final NamespaceKeyCriterion<K> criterion, final ModelProcessingPhase phase)  {
-        checkNotRegistered();
-
-        AddedToNamespace<C> addedToNs = new AddedToNamespace<>(phase);
-        addReq(addedToNs);
-        contextImpl(context).onNamespaceItemAddedAction(namespace, phase, criterion, addedToNs);
-        return addedToNs;
-    }
-
-    private <C extends StmtContext<?, ?, ?>> @NonNull AbstractPrerequisite<C> requiresCtxImpl(final C context,
-            final ModelProcessingPhase phase) {
-        checkNotRegistered();
-
-        PhaseFinished<C> phaseFin = new PhaseFinished<>();
-        addReq(phaseFin);
-        contextImpl(context).addPhaseCompletedListener(phase, phaseFin);
-        return phaseFin;
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    private <K, C extends Mutable<?, ?, ?>, N extends ParserNamespace<K, ? extends StmtContext<?, ?, ?>>>
-            AbstractPrerequisite<C> mutatesCtxImpl(final StmtContext<?, ?, ?> context, final Class<N> namespace,
-                    final K key, final ModelProcessingPhase phase) {
-        checkNotRegistered();
-
-        final PhaseModificationInNamespace<C> mod = new PhaseModificationInNamespace<>(EFFECTIVE_MODEL);
-        addReq(mod);
-        addMutation(mod);
-        contextImpl(context).onNamespaceItemAddedAction((Class) namespace, key, mod);
-        return mod;
-    }
-
-    private static StatementContextBase<?, ?, ?> contextImpl(final Object value) {
-        checkArgument(value instanceof StatementContextBase, "Supplied context %s is not provided by this reactor.",
-            value);
-        return StatementContextBase.class.cast(value);
-    }
-
-    boolean tryApply() {
-        checkState(action != null, "Action was not defined yet.");
-
-        if (removeSatisfied()) {
-            if (!actionApplied) {
-                action.apply(ctx);
-                actionApplied = true;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public <C extends Mutable<?, ?, ?>, T extends C> Prerequisite<C> mutatesCtx(final T context,
-            final ModelProcessingPhase phase) {
-        return addMutation(new PhaseMutation<>(contextImpl(context), phase));
-    }
-
-    @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);
-    }
-
-
-    @Override
-    public <K, N extends StatementNamespace<K, ?, ?>> Prerequisite<StmtContext<?, ?, ?>> requiresCtx(
-            final StmtContext<?, ?, ?> context, final Class<@NonNull N> namespace, final K key,
-            final ModelProcessingPhase phase) {
-        return requiresCtxImpl(context, namespace, key, phase);
-    }
-
-    @Override
-    public <K, N extends StatementNamespace<K, ?, ?>> Prerequisite<StmtContext<?, ?, ?>> requiresCtx(
-            final StmtContext<?, ?, ?> context, final Class<@NonNull N> namespace,
-            final NamespaceKeyCriterion<K> criterion, final ModelProcessingPhase phase) {
-        return requiresCtxImpl(context, namespace, criterion, phase);
-    }
-
-    @Override
-    public <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(
-            final StmtContext<?, ? extends D, ?> context) {
-        return requiresCtxImpl(context, FULL_DECLARATION).transform(StmtContext::declared);
-    }
-
-    @Override
-    @Deprecated
-    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);
-        return rawContext.transform(StmtContext::declared);
-    }
-
-    @Override
-    @Deprecated
-    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);
-    }
-
-    @Override
-    @Deprecated
-    public <E extends EffectiveStatement<?, ?>> Prerequisite<E> requiresEffective(
-            final StmtContext<?, ?, ? extends E> stmt) {
-        return requiresCtxImpl(stmt, EFFECTIVE_MODEL).transform(StmtContext::buildEffective);
-    }
-
-    @Override
-    @Deprecated
-    public <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>> Prerequisite<E>
-            requiresEffective(final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key) {
-        final AbstractPrerequisite<StmtContext<?, ?, E>> rawContext = requiresCtxImpl(context, namespace, key,
-            EFFECTIVE_MODEL);
-        return rawContext.transform(StmtContext::buildEffective);
-    }
-
-    @Override
-    @Deprecated
-    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);
-    }
-
-    @Override
-    @Deprecated
-    public <N extends ParserNamespace<?, ?>> Prerequisite<Mutable<?, ?, ?>> mutatesNs(final Mutable<?, ?, ?> context,
-            final Class<N> namespace) {
-        return addMutation(new NamespaceMutation<>(contextImpl(context), namespace));
-    }
-
-    @Override
-    public <K, E extends EffectiveStatement<?, ?>, N extends ParserNamespace<K, ? extends StmtContext<?, ?, ?>>>
-            AbstractPrerequisite<Mutable<?, ?, E>> mutatesEffectiveCtx(final StmtContext<?, ?, ?> context,
-                    final Class<N> namespace, final K key) {
-        return mutatesCtxImpl(context, namespace, key, EFFECTIVE_MODEL);
-    }
-
-    @Override
-    public <K, E extends EffectiveStatement<?, ?>, N extends ParserNamespace<K, ? extends StmtContext<?, ?, ?>>>
-            AbstractPrerequisite<Mutable<?, ?, E>> mutatesEffectiveCtxPath(final StmtContext<?, ?, ?> context,
-                    final Class<N> namespace, final Iterable<K> keys) {
-        checkNotRegistered();
-
-        final PhaseModificationInNamespacePath<Mutable<?, ?, E>, K, N> ret = new PhaseModificationInNamespacePath<>(
-                EFFECTIVE_MODEL, keys);
-        addReq(ret);
-        addMutation(ret);
-
-        ret.hookOnto(context, namespace);
-        return ret;
-    }
-
-    @Override
-    @SuppressWarnings("checkstyle:hiddenField")
-    public void apply(final InferenceAction action) {
-        checkState(this.action == null, "Action already defined to %s", this.action);
-        this.action = requireNonNull(action);
-    }
-
-    private abstract class AbstractPrerequisite<T> implements Prerequisite<T> {
-        private boolean done = false;
-        private T value;
-
-        @Override
-        @SuppressWarnings("checkstyle:hiddenField")
-        public final T resolve(final InferenceContext ctx) {
-            checkState(done);
-            checkArgument(ctx == ModifierImpl.this.ctx);
-            return verifyNotNull(value, "Attempted to access unavailable prerequisite %s", this);
-        }
-
-        final boolean isDone() {
-            return done;
-        }
-
-        @SuppressWarnings("checkstyle:hiddenField")
-        final boolean resolvePrereq(final T value) {
-            this.value = value;
-            this.done = true;
-            return isApplied();
-        }
-
-        final <O> @NonNull Prerequisite<O> transform(final Function<? super T, O> transformation) {
-            return context -> transformation.apply(resolve(context));
-        }
-
-        @Override
-        public final String toString() {
-            return addToStringAttributes(MoreObjects.toStringHelper(this).omitNullValues()).toString();
-        }
-
-        ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
-            return toStringHelper.add("value", value);
-        }
-    }
-
-    private final class PhaseMutation<C> extends AbstractPrerequisite<C> implements ContextMutation {
-        @SuppressWarnings("unchecked")
-        PhaseMutation(final StatementContextBase<?, ?, ?> context, final ModelProcessingPhase phase) {
-            context.addMutation(phase, this);
-            resolvePrereq((C) context);
-        }
-
-        @Override
-        public boolean isFinished() {
-            return isApplied();
-        }
-    }
-
-    private final class PhaseFinished<C extends StmtContext<?, ?, ?>> extends AbstractPrerequisite<C>
-            implements OnPhaseFinished {
-        @SuppressWarnings("unchecked")
-        @Override
-        public boolean phaseFinished(final StatementContextBase<?, ?, ?> context,
-                final ModelProcessingPhase finishedPhase) {
-            return resolvePrereq((C) context) || tryApply();
-        }
-    }
-
-    private final class NamespaceMutation<N extends ParserNamespace<?, ?>>
-            extends AbstractPrerequisite<Mutable<?, ?, ?>>  {
-        NamespaceMutation(final StatementContextBase<?, ?, ?> ctx, final Class<N> namespace) {
-            resolvePrereq(ctx);
-        }
-    }
-
-    private final class AddedToNamespace<C extends StmtContext<?, ?, ?>> extends AbstractPrerequisite<C>
-            implements OnNamespaceItemAdded, OnPhaseFinished {
-        private final ModelProcessingPhase phase;
-
-        AddedToNamespace(final ModelProcessingPhase phase) {
-            this.phase = requireNonNull(phase);
-        }
-
-        @Override
-        public void namespaceItemAdded(final StatementContextBase<?, ?, ?> context, final Class<?> namespace,
-                final Object key, final Object value) {
-            ((StatementContextBase<?, ?, ?>) value).addPhaseCompletedListener(phase, this);
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public boolean phaseFinished(final StatementContextBase<?, ?, ?> context,
-                final ModelProcessingPhase finishedPhase) {
-            return resolvePrereq((C) context) || tryApply();
-        }
-
-        @Override
-        ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
-            return super.addToStringAttributes(toStringHelper).add("phase", phase);
-        }
-    }
-
-    private final class PhaseModificationInNamespace<C extends Mutable<?, ?, ?>> extends AbstractPrerequisite<C>
-            implements OnNamespaceItemAdded, ContextMutation {
-        private final ModelProcessingPhase modPhase;
-
-        PhaseModificationInNamespace(final ModelProcessingPhase phase) {
-            checkArgument(phase != null, "Model processing phase must not be null");
-            this.modPhase = phase;
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public void namespaceItemAdded(final StatementContextBase<?, ?, ?> context, final Class<?> namespace,
-                final Object key, final Object value) {
-            StatementContextBase<?, ?, ?> targetCtx = contextImpl(value);
-            targetCtx.addMutation(modPhase, this);
-            resolvePrereq((C) targetCtx);
-        }
-
-        @Override
-        public boolean isFinished() {
-            return isApplied();
-        }
-    }
-
-    /**
-     * This similar to {@link PhaseModificationInNamespace}, but allows recursive descent until it finds the real
-     * target. The mechanics is driven as a sequence of prerequisites along a path: first we hook onto namespace to
-     * give us the first step. When it does, we hook onto the first item to provide us the second step and so on.
-     */
-    private final class PhaseModificationInNamespacePath<C extends Mutable<?, ?, ?>, K,
-            N extends ParserNamespace<K, ? extends StmtContext<?, ?, ?>>> extends AbstractPrerequisite<C>
-            implements OnNamespaceItemAdded, ContextMutation {
-        private final ModelProcessingPhase modPhase;
-        private final Iterable<K> keys;
-        private final Iterator<K> it;
-
-        PhaseModificationInNamespacePath(final ModelProcessingPhase phase, final Iterable<K> keys) {
-            this.modPhase = requireNonNull(phase);
-            this.keys = requireNonNull(keys);
-            it = keys.iterator();
-        }
-
-        @Override
-        public boolean isFinished() {
-            return isApplied();
-        }
-
-        @Override
-        public void namespaceItemAdded(final StatementContextBase<?, ?, ?> context, final Class<?> namespace,
-                final Object key, final Object value) {
-            LOG.debug("Action for {} got key {}", keys, key);
-
-            final StatementContextBase<?, ?, ?> target = contextImpl(value);
-            if (!target.isSupportedByFeatures()) {
-                LOG.debug("Key {} in {} is not supported", key, keys);
-                resolvePrereq(null);
-                action.prerequisiteUnavailable(this);
-                return;
-            }
-
-            // Hook onto target: we either have a modification of the target itself or one of its children.
-            target.addMutation(modPhase, this);
-            // We have completed the context -> target step, hence we are no longer directly blocking context from
-            // making forward progress.
-            context.removeMutation(modPhase, this);
-
-            if (!it.hasNext()) {
-                // Last step: we are done
-                if (resolvePrereq((C) value)) {
-                    tryApply();
-                }
-                return;
-            }
-
-            // Make sure target's storage notifies us when the next step becomes available.
-            hookOnto(target, namespace, it.next());
-        }
-
-        @Override
-        ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
-            return super.addToStringAttributes(toStringHelper).add("phase", modPhase).add("keys", keys);
-        }
-
-        void hookOnto(final StmtContext<?, ?, ?> context, final Class<?> namespace) {
-            checkArgument(it.hasNext(), "Namespace %s keys may not be empty", namespace);
-            hookOnto(contextImpl(context), namespace, it.next());
-        }
-
-        @SuppressWarnings("unchecked")
-        private void hookOnto(final StatementContextBase<?, ?, ?> context, final Class<?> namespace, final K key) {
-            context.onNamespaceItemAddedAction((Class) namespace, requireNonNull(key), this);
-        }
-    }
-}