void () { AtomicInteger parserInvocations = new AtomicInteger(); PsiBuilder builder = createBuilder("{x}"); PsiBuilder.Marker rootMarker = builder.mark(); PsiBuilder.Marker chameleon = builder.mark(); PsiBuilderUtil.advance(builder, 3); chameleon.collapse(new MyChameleon2Type() { @Override public void parse(PsiBuilder builder1) { parserInvocations.incrementAndGet(); super.parse(builder1); } }); rootMarker.done(ROOT); String treeString = """ Element(ROOT) Element(CHAMELEON_2) PsiElement(OTHER)('{') PsiElement(LETTER)('x') PsiElement(OTHER)('}') """; FlyweightCapableTreeStructure<LighterASTNode> tree = builder.getLightTree(); assertEquals(treeString, DebugUtil.lightTreeToString(tree, true)); assertEquals(1, parserInvocations.get()); assertEquals(treeString, DebugUtil.lightTreeToString(tree, true)); assertEquals(1, parserInvocations.get()); // new tree assertEquals(treeString, DebugUtil.lightTreeToString(builder.getLightTree(), true)); assertEquals(1, parserInvocations.get()); }