Use simple requireNonNull()
[yangtools.git] / yang / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / StatementContextWriter.java
index 6a50a43bd0cfb6ca7ee62ecf17a23bf6cbe9b65e..c0ef1180af43447f01c608f4cf2f9cc6d1a0c682 100644 (file)
@@ -7,10 +7,14 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Verify.verify;
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
 import java.util.Optional;
-import javax.annotation.Nonnull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
@@ -21,21 +25,24 @@ final class StatementContextWriter implements StatementWriter {
     private final ModelProcessingPhase phase;
     private final SourceSpecificContext ctx;
 
-    private StatementContextBase<?, ?, ?> current;
+    private AbstractResumedStatement<?, ?, ?> current;
 
     StatementContextWriter(final SourceSpecificContext ctx, final ModelProcessingPhase phase) {
-        this.ctx = Preconditions.checkNotNull(ctx);
-        this.phase = Preconditions.checkNotNull(phase);
+        this.ctx = requireNonNull(ctx);
+        this.phase = requireNonNull(phase);
     }
 
     @Override
     public Optional<? extends ResumedStatement> resumeStatement(final int childId) {
-        final Optional<StatementContextBase<?, ?, ?>> existing = ctx.lookupDeclaredChild(current, childId);
-        existing.ifPresent(this::resumeStatement);
-        return existing;
+        final AbstractResumedStatement<?, ?, ?> existing = lookupDeclaredChild(current, childId);
+        if (existing != null) {
+            resumeStatement(existing);
+            return Optional.of(existing);
+        }
+        return Optional.empty();
     }
 
-    private void resumeStatement(final StatementContextBase<?, ?, ?> child) {
+    private void resumeStatement(final AbstractResumedStatement<?, ?, ?> child) {
         if (child.isFullyDefined()) {
             child.walkChildren(phase);
             child.endDeclared(phase);
@@ -46,8 +53,9 @@ final class StatementContextWriter implements StatementWriter {
 
     @Override
     public void storeStatement(final int expectedChildren, final boolean fullyDefined) {
-        Preconditions.checkState(current != null);
-        Preconditions.checkArgument(expectedChildren >= 0);
+        checkState(current != null);
+        checkArgument(expectedChildren >= 0);
+        current.resizeSubstatements(expectedChildren);
 
         if (fullyDefined) {
             current.setFullyDefined();
@@ -55,32 +63,55 @@ final class StatementContextWriter implements StatementWriter {
     }
 
     @Override
-    public void startStatement(final int childId, @Nonnull final QName name, final String argument,
-            @Nonnull final StatementSourceReference ref) {
-        final Optional<StatementContextBase<?, ?, ?>> existing = ctx.lookupDeclaredChild(current, childId);
-        current = existing.isPresent() ? existing.get()
-                :  Verify.verifyNotNull(ctx.createDeclaredChild(current, childId, name, argument, ref));
+    public void startStatement(final int childId, final QName name, final String argument,
+            final StatementSourceReference ref) {
+        final AbstractResumedStatement<?, ?, ?> existing = lookupDeclaredChild(current, childId);
+        current = existing != null ? existing
+                : verifyNotNull(ctx.createDeclaredChild(current, childId, name, argument, ref));
     }
 
     @Override
-    public void endStatement(@Nonnull final StatementSourceReference ref) {
-        Preconditions.checkState(current != null);
+    public void endStatement(final StatementSourceReference ref) {
+        checkState(current != null);
         current.endDeclared(phase);
         exitStatement();
     }
 
-    @Nonnull
     @Override
     public ModelProcessingPhase getPhase() {
         return phase;
     }
 
     private void exitStatement() {
+        // TODO: AbstractResumedStatement should only ever have AbstractResumedStatement parents, which would:
+        //       - remove the StatementSource check
+        //       - allow endDeclared() to be moved to AbstractResumedStatement
+        //       - remove the need for verify()
         StatementContextBase<?, ?, ?> parentContext = current.getParentContext();
         while (parentContext != null && StatementSource.CONTEXT == parentContext.getStatementSource()) {
             parentContext.endDeclared(phase);
             parentContext = parentContext.getParentContext();
         }
-        current = parentContext;
+        if (parentContext != null) {
+            verify(parentContext instanceof AbstractResumedStatement, "Unexpected parent context %s", parentContext);
+            current = (AbstractResumedStatement<?, ?, ?>) parentContext;
+        } else {
+            current = null;
+        }
+    }
+
+    private static @Nullable AbstractResumedStatement<?, ?, ?> lookupDeclaredChild(
+            final AbstractResumedStatement<?, ?, ?> current, final int childId) {
+        if (current == null) {
+            return null;
+        }
+
+        // Fast path: we are entering a statement which was emitted in previous phase
+        AbstractResumedStatement<?, ?, ?> existing = current.lookupSubstatement(childId);
+        while (existing != null && StatementSource.CONTEXT == existing.getStatementSource()) {
+            existing = existing.lookupSubstatement(childId);
+        }
+
+        return existing;
     }
 }