Perform partial substatement initialization
[yangtools.git] / yang / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / AbstractResumedStatement.java
index ddfe0123dd89efb2000922cb6ea908d159917aaf..092c8a6108743c91bf84ece0fcbdd0c6c1ffcb8f 100644 (file)
@@ -10,9 +10,12 @@ 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 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;
@@ -36,28 +39,26 @@ 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 final @NonNull StatementSourceReference statementDeclSource;
-    private final StmtContext<?, ?, ?> originalCtx;
-    private final StmtContext<?, ?, ?> prevCopyCtx;
     private final String rawArgument;
 
+    private List<StatementContextBase<?, ?, ?>> effective = ImmutableList.of();
     private StatementMap substatements = StatementMap.empty();
+    private @Nullable D declaredInstance;
 
+    // Copy constructor
     AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
         super(original);
         this.statementDeclSource = original.statementDeclSource;
         this.rawArgument = original.rawArgument;
-        this.originalCtx = original.getOriginalCtx().orElse(original);
-        this.prevCopyCtx = original;
         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.originalCtx = null;
-        this.prevCopyCtx = null;
+        this.rawArgument = def.support().internArgument(rawArgument);
     }
 
     AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
@@ -65,18 +66,16 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
         super(def, CopyHistory.of(copyType, CopyHistory.original()));
         this.statementDeclSource = requireNonNull(ref);
         this.rawArgument = rawArgument;
-        this.originalCtx = null;
-        this.prevCopyCtx = null;
     }
 
     @Override
-    public final Optional<StmtContext<?, ?, ?>> getOriginalCtx() {
-        return Optional.ofNullable(originalCtx);
+    public final Optional<StmtContext<A, D, E>> getOriginalCtx() {
+        return Optional.empty();
     }
 
     @Override
-    public final Optional<? extends StmtContext<?, ?, ?>> getPreviousCopyCtx() {
-        return Optional.ofNullable(prevCopyCtx);
+    public final Optional<StmtContext<A, D, E>> getPreviousCopyCtx() {
+        return Optional.empty();
     }
 
     @Override
@@ -91,7 +90,46 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
 
     @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 final void addEffectiveSubstatement(final Mutable<?, ?, ?> substatement) {
+        effective = addEffectiveSubstatement(effective, substatement);
+    }
+
+    @Override
+    final void addEffectiveSubstatementsImpl(final Collection<? extends Mutable<?, ?, ?>> statements) {
+        effective = addEffectiveSubstatementsImpl(effective, statements);
+    }
+
+    @Override
+    public final D buildDeclared() {
+        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
@@ -143,6 +181,16 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
         return ret;
     }
 
+    @Override
+    final boolean hasEmptySubstatements() {
+        return substatements.size() == 0 && effective.isEmpty();
+    }
+
+    @Override
+    final Iterable<StatementContextBase<?, ?, ?>> effectiveChildrenToComplete() {
+        return effective;
+    }
+
     /**
      * Lookup substatement by its offset in this statement.
      *
@@ -159,7 +207,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);
         });