Remove ReactorStmtCtx.checkLocalNamespaceAllowed()
[yangtools.git] / yang / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / AbstractResumedStatement.java
index 7c7f0db7b66b956d6d14559bd57015efe449d5bb..20a390d1e58d3d451335e028a206c39e8919848f 100644 (file)
@@ -10,13 +10,16 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 import static com.google.common.base.Preconditions.checkState;
 import static java.util.Objects.requireNonNull;
 
+import com.google.common.collect.ImmutableList;
 import java.util.Collection;
+import java.util.List;
 import java.util.Optional;
+import java.util.stream.Stream;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 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.StatementDefinition;
-import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
@@ -24,6 +27,8 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter.ResumedStatement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Intermediate subclass of StatementContextBase facing the parser stream via implementation of ResumedStatement. This
@@ -35,10 +40,14 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter.Resumed
  */
 abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
         extends StatementContextBase<A, D, E> implements ResumedStatement {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractResumedStatement.class);
+
     private final @NonNull StatementSourceReference statementDeclSource;
     private final String rawArgument;
 
+    private List<ReactorStmtCtx<?, ?, ?>> effective = ImmutableList.of();
     private StatementMap substatements = StatementMap.empty();
+    private @Nullable D declaredInstance;
 
     // Copy constructor
     AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
@@ -46,55 +55,95 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
         this.statementDeclSource = original.statementDeclSource;
         this.rawArgument = original.rawArgument;
         this.substatements = original.substatements;
+        this.declaredInstance = original.declaredInstance;
     }
 
     AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
             final String rawArgument) {
         super(def);
         this.statementDeclSource = requireNonNull(ref);
-        this.rawArgument = def.internArgument(rawArgument);
+        this.rawArgument = def.support().internArgument(rawArgument);
     }
 
     AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
             final String rawArgument, final CopyType copyType) {
-        super(def, CopyHistory.of(copyType, CopyHistory.original()));
+        super(def, copyType);
         this.statementDeclSource = requireNonNull(ref);
         this.rawArgument = rawArgument;
     }
 
     @Override
-    public final Optional<StmtContext<?, ?, ?>> getOriginalCtx() {
+    public final Optional<StmtContext<A, D, E>> getOriginalCtx() {
         return Optional.empty();
     }
 
     @Override
-    public final Optional<? extends StmtContext<?, ?, ?>> getPreviousCopyCtx() {
+    public final Optional<StmtContext<A, D, E>> getPreviousCopyCtx() {
         return Optional.empty();
     }
 
     @Override
-    public final StatementSourceReference getStatementSourceReference() {
+    public final StatementSourceReference sourceReference() {
         return statementDeclSource;
     }
 
     @Override
-    public final String rawStatementArgument() {
+    public final String rawArgument() {
         return rawArgument;
     }
 
     @Override
     public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
-        return substatements.values();
+        return substatements;
+    }
+
+    @Override
+    public final Collection<? extends Mutable<?, ?, ?>> mutableEffectiveSubstatements() {
+        return mutableEffectiveSubstatements(effective);
+    }
+
+    @Override
+    public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef) {
+        effective = removeStatementFromEffectiveSubstatements(effective, statementDef);
+    }
+
+    @Override
+    public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef,
+            final String statementArg) {
+        effective = removeStatementFromEffectiveSubstatements(effective, statementDef, statementArg);
     }
 
     @Override
-    public @NonNull StatementDefinition getDefinition() {
-        return getPublicDefinition();
+    public final void addEffectiveSubstatement(final Mutable<?, ?, ?> substatement) {
+        effective = addEffectiveSubstatement(effective, substatement);
     }
 
     @Override
-    public @NonNull StatementSourceReference getSourceReference() {
-        return getStatementSourceReference();
+    final void addEffectiveSubstatementsImpl(final Collection<? extends Mutable<?, ?, ?>> statements) {
+        effective = addEffectiveSubstatementsImpl(effective, statements);
+    }
+
+    @Override
+    public final D declared() {
+        final D existing;
+        return (existing = declaredInstance) != null ? existing : loadDeclared();
+    }
+
+    private @NonNull D loadDeclared() {
+        final ModelProcessingPhase phase = getCompletedPhase();
+        checkState(phase == ModelProcessingPhase.FULL_DECLARATION || phase == ModelProcessingPhase.EFFECTIVE_MODEL,
+                "Cannot build declared instance after phase %s", phase);
+        return declaredInstance = definition().getFactory().createDeclared(this);
+    }
+
+    @Override
+    public StatementDefinition getDefinition() {
+        return publicDefinition();
+    }
+
+    @Override
+    public StatementSourceReference getSourceReference() {
+        return sourceReference();
     }
 
     @Override
@@ -121,7 +170,7 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
                     final String argument) {
         final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase();
         checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
-                "Declared statement cannot be added in effective phase at: %s", getStatementSourceReference());
+                "Declared statement cannot be added in effective phase at: %s", sourceReference());
 
         final Optional<StatementSupport<?, ?, ?>> implicitParent =
                 definition().getImplicitParentFor(def.getPublicView());
@@ -136,6 +185,61 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
         return ret;
     }
 
+    @Override
+    final AbstractResumedStatement<A, D, E> unmodifiedEffectiveSource() {
+        // This statement is comes from the source
+        return this;
+    }
+
+    @Override
+    final boolean hasEmptySubstatements() {
+        return substatements.size() == 0 && effective.isEmpty();
+    }
+
+    @Override
+    final boolean noSensitiveSubstatements() {
+        return hasEmptySubstatements()
+            || noSensitiveSubstatements(substatements) && noSensitiveSubstatements(effective);
+    }
+
+    @Override
+    final Iterable<ReactorStmtCtx<?, ?, ?>> effectiveChildrenToComplete() {
+        return effective;
+    }
+
+    @Override
+    final Stream<? extends @NonNull StmtContext<?, ?, ?>> streamDeclared() {
+        return declaredSubstatements().stream().filter(StmtContext::isSupportedToBuildEffective);
+    }
+
+    @Override
+    final Stream<? extends @NonNull StmtContext<?, ?, ?>> streamEffective() {
+        return effective.stream().filter(StmtContext::isSupportedToBuildEffective);
+    }
+
+    @Override
+    final void markNoParentRef() {
+        markNoParentRef(substatements);
+        markNoParentRef(effective);
+    }
+
+    @Override
+    final int sweepSubstatements() {
+        // First we need to sweep all statements, which may trigger sweeps all across the place, for example:
+        // - 'effective' member sweeping a 'substatements' member
+        // - 'substatements' member sweeping a 'substatements' member which came before it during iteration
+        // We then iterate once again, counting what remains unswept
+        sweep(substatements);
+        sweep(effective);
+        final int count = countUnswept(substatements) + countUnswept(effective);
+        if (count != 0) {
+            LOG.debug("{} children left to sweep from {}", count, this);
+        }
+        substatements = null;
+        effective = null;
+        return count;
+    }
+
     /**
      * Lookup substatement by its offset in this statement.
      *
@@ -152,7 +256,7 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
 
     final void walkChildren(final ModelProcessingPhase phase) {
         checkState(isFullyDefined());
-        substatements.values().forEach(stmt -> {
+        substatements.forEach(stmt -> {
             stmt.walkChildren(phase);
             stmt.endDeclared(phase);
         });