boolean (ErrorState state, PsiBuilder builder, int level, IElementType chunkType, boolean checkBraces, Parser parser, Parser eatMoreCondition) { ArrayDeque<Pair<PsiBuilder.Marker, PsiBuilder.Marker>> parens = new ArrayDeque<>(4); ArrayDeque<Pair<PsiBuilder.Marker, Integer>> siblings = new ArrayDeque<>(); PsiBuilder.Marker marker = null; IElementType lBrace = checkBraces && state.braces != null && state.braces.length > 0 ? state.braces[0].getLeftBraceType() : null; IElementType rBrace = lBrace != null ? state.braces[0].getRightBraceType() : null; int totalCount = 0; int tokenCount = 0; if (lBrace != null) { int tokenIdx = -1; while (builder.rawLookup(tokenIdx) == TokenType.WHITE_SPACE) tokenIdx --; LighterASTNode doneMarker = builder.rawLookup(tokenIdx) == lBrace ? builder.getLatestDoneMarker() : null; if (doneMarker != null && doneMarker.getStartOffset() == builder.rawTokenTypeStart(tokenIdx) && doneMarker.getTokenType() == TokenType.ERROR_ELEMENT) { parens.add(Pair.create(((PsiBuilder.Marker)doneMarker).precede(), null)); } } int c = current_position_(builder); while (true) { IElementType tokenType = builder.getTokenType(); if (lBrace != null && (tokenType == lBrace || tokenType == rBrace && !parens.isEmpty())) { if (marker != null) { marker.done(chunkType); siblings.addFirst(Pair.create(marker, 1)); marker = null; tokenCount = 0; } if (tokenType == lBrace) { Pair<PsiBuilder.Marker, Integer> prev = siblings.peek(); parens.addFirst(Pair.create(builder.mark(), Pair.getFirst(prev))); } checkSiblings(chunkType, parens, siblings); state.tokenAdvancer.parse(builder, level); if (tokenType == rBrace) { Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair = parens.removeFirst(); pair.first.done(chunkType); // drop all markers inside parens while (!siblings.isEmpty() && siblings.getFirst().first != pair.second) { siblings.removeFirst(); } siblings.addFirst(Pair.create(pair.first, 1)); checkSiblings(chunkType, parens, siblings); } } else { if (marker == null) { marker = builder.mark(); marker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, null); } boolean result = (!parens.isEmpty() || eatMoreCondition.parse(builder, level + 1)) && parser.parse(builder, level + 1); if (result) { tokenCount++; totalCount++; } else { break; } } if (tokenCount >= MAX_CHILDREN_IN_TREE) { marker.done(chunkType); siblings.addFirst(Pair.create(marker, 1)); checkSiblings(chunkType, parens, siblings); marker = null; tokenCount = 0; } if (!empty_element_parsed_guard_(builder, "parseAsTree", c)) break; c = current_position_(builder); } if (marker != null) marker.drop(); for (Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair : parens) { pair.first.drop(); } return totalCount != 0; }