protected TemplateModel calculateResult()

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
                );
            }
        }