in freemarker-core/src/main/java/freemarker/core/BuiltInsForSequences.java [1268:1353]
protected TemplateModel calculateResult(
final TemplateModelIterator lhoIterator, final TemplateModel lho,
boolean lhoIsSequence, final ElementTransformer elementTransformer,
final Environment env) throws TemplateException {
if (!isLazilyGeneratedResultEnabled()) {
if (!lhoIsSequence) {
throw _MessageUtil.newLazilyGeneratedCollectionMustBeSequenceException(drop_whileBI.this);
}
List<TemplateModel> resultList = new ArrayList<>();
while (lhoIterator.hasNext()) {
TemplateModel element = lhoIterator.next();
if (!elementMatches(element, elementTransformer, env)) {
resultList.add(element);
while (lhoIterator.hasNext()) {
resultList.add(lhoIterator.next());
}
break;
}
}
return new TemplateModelListSequence(resultList);
} else {
return new LazilyGeneratedCollectionModelWithUnknownSize(
new TemplateModelIterator() {
boolean dropMode = true;
boolean prefetchDone;
TemplateModel prefetchedElement;
boolean prefetchedEndOfIterator;
@Override
public TemplateModel next() throws TemplateModelException {
ensurePrefetchDone();
if (prefetchedEndOfIterator) {
throw new IllegalStateException("next() was called when hasNext() is false");
}
prefetchDone = false;
return prefetchedElement;
}
@Override
public boolean hasNext() throws TemplateModelException {
ensurePrefetchDone();
return !prefetchedEndOfIterator;
}
private void ensurePrefetchDone() throws TemplateModelException {
if (prefetchDone) {
return;
}
if (dropMode) {
boolean foundElement = false;
dropElements: while (lhoIterator.hasNext()) {
TemplateModel element = lhoIterator.next();
try {
if (!elementMatches(element, elementTransformer, env)) {
prefetchedElement = element;
foundElement = true;
break dropElements;
}
} catch (TemplateException e) {
throw new _TemplateModelException(e, env,
"Failed to transform element");
}
}
dropMode = false;
if (!foundElement) {
prefetchedEndOfIterator = true;
prefetchedElement = null;
}
} else {
if (lhoIterator.hasNext()) {
TemplateModel element = lhoIterator.next();
prefetchedElement = element;
} else {
prefetchedEndOfIterator = true;
prefetchedElement = null;
}
}
prefetchDone = true;
}
},
lhoIsSequence
);
}
}