Bug 2366 - Effective statments impl merge, retest & bugfix
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / BuildGlobalContext.java
index b5380224047a81674756715b0d2fed91b35349b8..b4c7bdd204ade5adb2ec122c33f56e956dd168b8 100644 (file)
@@ -7,6 +7,14 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite;
+import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace;
+
+import java.util.Map.Entry;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
+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;
@@ -39,25 +47,39 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.SourceSpecificContext
 class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBehaviour.Registry {
 
     private static final List<ModelProcessingPhase> PHASE_EXECUTION_ORDER = ImmutableList.<ModelProcessingPhase>builder()
-            .add(ModelProcessingPhase.SourceLinkage)
-            .add(ModelProcessingPhase.StatementDefinition)
-            .add(ModelProcessingPhase.FullDeclaration)
-            .add(ModelProcessingPhase.EffectiveModel)
+            .add(ModelProcessingPhase.SOURCE_LINKAGE)
+            .add(ModelProcessingPhase.STATEMENT_DEFINITION)
+            .add(ModelProcessingPhase.FULL_DECLARATION)
+            .add(ModelProcessingPhase.EFFECTIVE_MODEL)
             .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(Map<ModelProcessingPhase, StatementSupportBundle> supports) {
         super();
-        this.supports = supports;
+        this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null");
+    }
+
+    public BuildGlobalContext(Map<ModelProcessingPhase, StatementSupportBundle> supports,  Map<ValidationBundleType,Collection<?>> supportedValidation) {
+        super();
+        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) {
+        return supports.get(currentPhase);
     }
 
     public void addSource(@Nonnull StatementStreamSource source) {
@@ -66,7 +88,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
 
     @Override
     public StorageNodeType getStorageNodeType() {
-        return StorageNodeType.Global;
+        return StorageNodeType.GLOBAL;
     }
 
     @Override
@@ -81,12 +103,12 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
 
     @Override
     public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> getNamespaceBehaviour(Class<N> type) {
-        NamespaceBehaviourWithListeners<?, ?, ?> potential = namespaces.get(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) {
@@ -96,11 +118,9 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
              * 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) {
@@ -126,7 +146,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
     }
 
     private EffectiveModelContext transform() {
-        Preconditions.checkState(finishedPhase == ModelProcessingPhase.EffectiveModel);
+        Preconditions.checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
         List<DeclaredStatement<?>> rootStatements = new ArrayList<>();
         for(SourceSpecificContext source : sources) {
             DeclaredStatement<?> root = source.getRoot().buildDeclared();
@@ -135,6 +155,32 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
         return new EffectiveModelContext(rootStatements);
     }
 
+    public EffectiveSchemaContext buildEffective() throws SourceException, ReactorException {
+        for(ModelProcessingPhase phase : PHASE_EXECUTION_ORDER) {
+            startPhase(phase);
+            loadPhaseStatements();
+            completePhaseActions();
+            endPhase(phase);
+        }
+        return transformEffective();
+    }
+
+    private EffectiveSchemaContext transformEffective() {
+        Preconditions.checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
+        List<DeclaredStatement<?>> rootStatements = new ArrayList<>();
+        List<EffectiveStatement<?,?>> rootEffectiveStatements = new ArrayList<>();
+
+        for(SourceSpecificContext source : sources) {
+            DeclaredStatement<?> root = source.getRoot().buildDeclared();
+            rootStatements.add(root);
+
+            EffectiveStatement<?,?> rootEffective = source.getRoot().buildEffective();
+            rootEffectiveStatements.add(rootEffective);
+        }
+
+        return new EffectiveSchemaContext(rootStatements,rootEffectiveStatements);
+    }
+
     private void startPhase(ModelProcessingPhase phase) {
         Preconditions.checkState(Objects.equals(finishedPhase, phase.getPreviousPhase()));
         for(SourceSpecificContext source : sources) {
@@ -152,7 +198,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
 
     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) {
@@ -160,14 +206,20 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
                 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);
                     }
                 }
             }