package org.intellij.plugins.markdown.lang.parser; import com.intellij.lang.PsiBuilder; import org.intellij.markdown.IElementType; import org.intellij.markdown.MarkdownElementTypes; import org.intellij.markdown.ast.ASTNode; import org.intellij.markdown.ast.LeafASTNode; import org.intellij.markdown.ast.visitors.RecursiveVisitor; import org.intellij.plugins.markdown.lang.MarkdownElementType; import org.jetbrains.annotations.NotNull; public class PsiBuilderFillingVisitor extends RecursiveVisitor { @NotNull private final PsiBuilder builder; public PsiBuilderFillingVisitor(@NotNull PsiBuilder builder) { this.builder = builder; } @Override public void visitNode(@NotNull ASTNode node) { if (node instanceof LeafASTNode) { /* a hack for the link reference definitions: * they are being parsed independent from link references and * the link titles and urls are tokens instead of composite elements */ final IElementType type = node.getType(); if (type != MarkdownElementTypes.LINK_LABEL && type != MarkdownElementTypes.LINK_DESTINATION) { return; } } ensureBuilderInPosition(node.getStartOffset()); final PsiBuilder.Marker marker = builder.mark(); super.visitNode(node); ensureBuilderInPosition(node.getEndOffset()); marker.done(MarkdownElementType.platformType(node.getType())); } private void ensureBuilderInPosition(int position) { while (builder.getCurrentOffset() < position) { builder.advanceLexer(); } if (builder.getCurrentOffset() != position) { throw new AssertionError("parsed tree and lexer are unsynchronized"); } } }