1 /* 2 * Copyright (C) 2007 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.common.base; 16 17 import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT; 18 import static com.google.common.base.Preconditions.checkState; 19 20 import com.google.common.annotations.GwtCompatible; 21 import com.google.errorprone.annotations.CanIgnoreReturnValue; 22 import java.util.Iterator; 23 import java.util.NoSuchElementException; 24 import javax.annotation.CheckForNull; 25 import org.checkerframework.checker.nullness.qual.Nullable; 26 27 /** 28 * Note this class is a copy of {@link com.google.common.collect.AbstractIterator} (for dependency 29 * reasons). 30 */ 31 @GwtCompatible 32 @ElementTypesAreNonnullByDefault 33 abstract class AbstractIterator<T extends @Nullable Object> implements Iterator<T> { 34 private State state = State.NOT_READY; 35 AbstractIterator()36 protected AbstractIterator() {} 37 38 private enum State { 39 READY, 40 NOT_READY, 41 DONE, 42 FAILED, 43 } 44 45 @CheckForNull private T next; 46 47 @CheckForNull computeNext()48 protected abstract T computeNext(); 49 50 @CanIgnoreReturnValue 51 @CheckForNull endOfData()52 protected final T endOfData() { 53 state = State.DONE; 54 return null; 55 } 56 57 @Override hasNext()58 public final boolean hasNext() { 59 checkState(state != State.FAILED); 60 switch (state) { 61 case DONE: 62 return false; 63 case READY: 64 return true; 65 default: 66 } 67 return tryToComputeNext(); 68 } 69 tryToComputeNext()70 private boolean tryToComputeNext() { 71 state = State.FAILED; // temporary pessimism 72 next = computeNext(); 73 if (state != State.DONE) { 74 state = State.READY; 75 return true; 76 } 77 return false; 78 } 79 80 @Override 81 @ParametricNullness next()82 public final T next() { 83 if (!hasNext()) { 84 throw new NoSuchElementException(); 85 } 86 state = State.NOT_READY; 87 // Safe because hasNext() ensures that tryToComputeNext() has put a T into `next`. 88 T result = uncheckedCastNullableTToT(next); 89 next = null; 90 return result; 91 } 92 93 @Override remove()94 public final void remove() { 95 throw new UnsupportedOperationException(); 96 } 97 } 98