package jetbrains.mps.internal.collections.runtime.impl;
/*Generated by MPS */
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import java.util.Iterator;
import java.util.NoSuchElementException;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.StopIteratingException;
public class TranslatingSequence<U, V> extends AbstractChainedSequence<U, V> implements Iterable<V> {
private final _FunctionTypes._return_P1_E0<? extends Iterable<V>, ? super U> translator;
public TranslatingSequence(Iterable<U> input, _FunctionTypes._return_P1_E0<? extends Iterable<V>, ? super U> translator) {
super(input);
if (translator == null) {
throw new NullPointerException();
}
this.translator = translator;
}
@Override
public Iterator<V> iterator() {
return new TranslatingSequence.TranslatingIterator();
}
private class TranslatingIterator implements Iterator<V> {
private Iterator<U> inputIt;
private Iterator<V> transIt;
private HasNextState hasNext = HasNextState.UNKNOWN;
private V next;
private TranslatingIterator() {
}
@Override
public boolean hasNext() {
if (inputIt == null) {
init();
}
if (hasNext.unknown()) {
moveToNext();
}
return hasNext.hasNext();
}
@Override
public V next() {
if (inputIt == null) {
init();
}
if (hasNext.unknown()) {
moveToNext();
}
if (!((hasNext.hasNext()))) {
throw new NoSuchElementException();
}
return clearNext();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private void init() {
inputIt = getInput().iterator();
}
private void moveToNext() {
hasNext = HasNextState.AT_END;
next = null;
do {
try {
if (transIt != null && transIt.hasNext()) {
V tmp = transIt.next();
if (Sequence.IGNORE_NULL_VALUES) {
if (tmp == null) {
continue;
}
}
next = tmp;
hasNext = HasNextState.HAS_NEXT;
break;
}
} catch (StopIteratingException stop) {
break;
}
if (inputIt.hasNext()) {
try {
Iterable<V> transSeq = translator.invoke(inputIt.next());
if (Sequence.USE_NULL_SEQUENCE) {
if (transSeq == null) {
transSeq = NullSequence.instance();
}
}
transIt = transSeq.iterator();
} catch (StopIteratingException illegal) {
throw new IllegalStateException(illegal);
}
} else {
break;
}
} while (true);
}
private V clearNext() {
V tmp = next;
next = null;
hasNext = HasNextState.UNKNOWN;
return tmp;
}
}
}