*/
package org.opendaylight.yangtools.yang.parser.stmt.reactor;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
-
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.common.QName;
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;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
+import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.SourceSpecificContext.PhaseCompletionProgress;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBehaviour.Registry {
.build();
private final Map<QName,StatementDefinitionContext<?,?,?>> definitions = new HashMap<>();
- private final Map<Class<?>,NamespaceBehaviourWithListeners<?, ?, ?>> namespaces = new HashMap<>();
+ private final Map<Class<?>,NamespaceBehaviourWithListeners<?, ?, ?>> supportedNamespaces = new HashMap<>();
private final Map<ModelProcessingPhase,StatementSupportBundle> supports;
private final Set<SourceSpecificContext> sources = new HashSet<>();
- private ModelProcessingPhase currentPhase;
- private ModelProcessingPhase finishedPhase;
+ private ModelProcessingPhase currentPhase = ModelProcessingPhase.INIT;
+ private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT;
+
+ public BuildGlobalContext(final Map<ModelProcessingPhase, StatementSupportBundle> supports) {
+ super();
+ this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null");
+ }
- public BuildGlobalContext(Map<ModelProcessingPhase, StatementSupportBundle> supports) {
+ public BuildGlobalContext(final Map<ModelProcessingPhase, StatementSupportBundle> supports, final Map<ValidationBundleType,Collection<?>> supportedValidation) {
super();
- this.supports = supports;
+ this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null");
+
+ Set<Entry<ValidationBundleType, Collection<?>>> validationBundles = supportedValidation.entrySet();
+ for (Entry<ValidationBundleType, Collection<?>> validationBundle : validationBundles) {
+ addToNs(ValidationBundlesNamespace.class, validationBundle.getKey(), validationBundle.getValue());
+ }
}
- public StatementSupportBundle getSupportsForPhase(ModelProcessingPhase currentPhase) {
+ public StatementSupportBundle getSupportsForPhase(final ModelProcessingPhase currentPhase) {
return supports.get(currentPhase);
}
- public void addSource(@Nonnull StatementStreamSource source) {
+ public void addSource(@Nonnull final StatementStreamSource source) {
sources.add(new SourceSpecificContext(this,source));
}
}
@Override
- public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> getNamespaceBehaviour(Class<N> type) {
- NamespaceBehaviourWithListeners<?, ?, ?> potential = namespaces.get(type);
+ public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> getNamespaceBehaviour(final Class<N> type) {
+ NamespaceBehaviourWithListeners<?, ?, ?> potential = supportedNamespaces.get(type);
if (potential == null) {
NamespaceBehaviour<K, V, N> potentialRaw = supports.get(currentPhase).getNamespaceBehaviour(type);
if(potentialRaw != null) {
potential = new NamespaceBehaviourWithListeners<>(potentialRaw);
- namespaces.put(type, potential);
+ supportedNamespaces.put(type, potential);
}
}
if (potential != null) {
* Safe cast, previous checkState checks equivalence of key from
* which type argument are derived
*/
- @SuppressWarnings("unchecked")
- NamespaceBehaviourWithListeners<K, V, N> casted = (NamespaceBehaviourWithListeners<K, V, N>) potential;
- return casted;
+ return (NamespaceBehaviourWithListeners<K, V, N>) potential;
}
- throw new NamespaceNotAvailableException("Namespace " + type + "is not available in phase " + currentPhase);
+ throw new NamespaceNotAvailableException("Namespace " + type + " is not available in phase " + currentPhase);
}
- public StatementDefinitionContext<?, ?, ?> getStatementDefinition(QName name) {
+ public StatementDefinitionContext<?, ?, ?> getStatementDefinition(final QName name) {
StatementDefinitionContext<?, ?, ?> potential = definitions.get(name);
if(potential == null) {
StatementSupport<?, ?, ?> potentialRaw = supports.get(currentPhase).getStatementDefinition(name);
return new EffectiveSchemaContext(rootStatements,rootEffectiveStatements);
}
- private void startPhase(ModelProcessingPhase phase) {
+ private void startPhase(final ModelProcessingPhase phase) {
Preconditions.checkState(Objects.equals(finishedPhase, phase.getPreviousPhase()));
for(SourceSpecificContext source : sources) {
source.startPhase(phase);
}
}
+ private SomeModifiersUnresolvedException addSourceExceptions(final SomeModifiersUnresolvedException buildFailure,
+ final List<SourceSpecificContext> sourcesToProgress) {
+ for(SourceSpecificContext failedSource : sourcesToProgress) {
+ SourceException sourceEx = failedSource.failModifiers(currentPhase);
+ buildFailure.addSuppressed(sourceEx);
+ }
+ return buildFailure;
+ }
+
private void completePhaseActions() throws ReactorException {
Preconditions.checkState(currentPhase != null);
- ArrayList<SourceSpecificContext> sourcesToProgress = Lists.newArrayList(sources);
+ List<SourceSpecificContext> sourcesToProgress = Lists.newArrayList(sources);
try {
boolean progressing = true;
while(progressing) {
progressing = false;
Iterator<SourceSpecificContext> currentSource = sourcesToProgress.iterator();
while(currentSource.hasNext()) {
- PhaseCompletionProgress sourceProgress = currentSource.next().tryToCompletePhase(currentPhase);
+ SourceSpecificContext nextSourceCtx = currentSource.next();
+ PhaseCompletionProgress sourceProgress = nextSourceCtx.tryToCompletePhase(currentPhase);
switch (sourceProgress) {
case FINISHED:
currentSource.remove();
+ // Fallback to progress, since we were able to make progress in computation
case PROGRESS:
progressing = true;
+ break;
case NO_PROGRESS:
- // Noop;
+ // Noop
+ break;
+ default:
+ throw new IllegalStateException("Unsupported phase progress " + sourceProgress);
}
}
}
}
if(!sourcesToProgress.isEmpty()) {
SomeModifiersUnresolvedException buildFailure = new SomeModifiersUnresolvedException(currentPhase);
- for(SourceSpecificContext failedSource : sourcesToProgress) {
- SourceException sourceEx = failedSource.failModifiers(currentPhase);
- buildFailure.addSuppressed(sourceEx);
- }
- throw buildFailure;
+ buildFailure = addSourceExceptions(buildFailure, sourcesToProgress);
+ throw buildFailure;
}
}
- private void endPhase(ModelProcessingPhase phase) {
+ private void endPhase(final ModelProcessingPhase phase) {
Preconditions.checkState(currentPhase == phase);
finishedPhase = currentPhase;
}