Do not force materialization when not needed
[yangtools.git] / yang / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / AbstractResumedStatement.java
index 8a92906875077204da7184a75ed2ffcae9f26ad6..b83df70b538c5d45a1bc8a84f395026cf62a6ce9 100644 (file)
@@ -28,6 +28,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
@@ -39,10 +41,12 @@ 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<StatementContextBase<?, ?, ?>> effective = ImmutableList.of();
+    private List<ReactorStmtCtx<?, ?, ?>> effective = ImmutableList.of();
     private StatementMap substatements = StatementMap.empty();
     private @Nullable D declaredInstance;
 
@@ -121,7 +125,7 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
     }
 
     @Override
-    public final D buildDeclared() {
+    public final D declared() {
         final D existing;
         return (existing = declaredInstance) != null ? existing : loadDeclared();
     }
@@ -167,7 +171,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());
@@ -188,7 +192,7 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
     }
 
     @Override
-    final Iterable<StatementContextBase<?, ?, ?>> effectiveChildrenToComplete() {
+    final Iterable<ReactorStmtCtx<?, ?, ?>> effectiveChildrenToComplete() {
         return effective;
     }
 
@@ -202,6 +206,29 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
         return effective.stream();
     }
 
+    @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.
      *