// Path: src/main/java/org/antlr/jetbrains/st4plugin/psi/STTokenTypes.java
// public class STTokenTypes {
// 
//     private static final List<TokenIElementType> TOKEN_ELEMENT_TYPES = PSIElementTypeFactory.getTokenIElementTypes(STLanguage.INSTANCE);
//     private static final List<RuleIElementType> RULE_ELEMENT_TYPES = PSIElementTypeFactory.getRuleIElementTypes(STLanguage.INSTANCE);
// 
//     public static RuleIElementType getRuleElementType(@MagicConstant(valuesFromClass = STParser.class) int ruleIndex) {
//         return RULE_ELEMENT_TYPES.get(ruleIndex);
//     }
// 
//     public static TokenIElementType getTokenElementType(@MagicConstant(valuesFromClass = STLexer.class) int ruleIndex) {
//         return TOKEN_ELEMENT_TYPES.get(ruleIndex);
//     }
// }
// 
// Path: src/main/java/org/antlr/jetbrains/st4plugin/psi/STTokenTypes.java
// public static RuleIElementType getRuleElementType(@MagicConstant(valuesFromClass = STParser.class) int ruleIndex) {
//     return RULE_ELEMENT_TYPES.get(ruleIndex);
// }
// 
// Path: src/main/java/org/antlr/jetbrains/st4plugin/psi/STTokenTypes.java
// public static TokenIElementType getTokenElementType(@MagicConstant(valuesFromClass = STLexer.class) int ruleIndex) {
//     return TOKEN_ELEMENT_TYPES.get(ruleIndex);
// }


import com.intellij.lang.ASTNode;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import org.antlr.jetbrains.st4plugin.parsing.STLexer;
import org.antlr.jetbrains.st4plugin.parsing.STParser;
import org.antlr.jetbrains.st4plugin.psi.STTokenTypes;
import org.jetbrains.annotations.NotNull;
import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey;
import static org.antlr.jetbrains.st4plugin.psi.STTokenTypes.getRuleElementType;
import static org.antlr.jetbrains.st4plugin.psi.STTokenTypes.getTokenElementType;
                        .setTextAttributes(STGroupSemanticHighlightAnnotator.TEMPLATE_PARAM);
            } else if (isOptionId(element)) {
                holder.createInfoAnnotation(element, null)
                        .setTextAttributes(OPTION);
            } else if (isCall(element)) {
                holder.createInfoAnnotation(element, null)
                        .setTextAttributes(STGroupSyntaxHighlighter.TEMPLATE_NAME);
            }
        }

        if (isTag(element)) {
            // use a white/dark background instead of the default green from injected languages
            holder.createInfoAnnotation(element, null)
                    .setTextAttributes(ST_TAG);
        }

        if (element.getNode().getElementType() == getRuleElementType(STParser.RULE_ifstat)) {
            for (ASTNode ldelim : element.getNode().getChildren(TokenSet.create(getTokenElementType(STLexer.LDELIM)))) {
                ASTNode rdelim = element.getNode().findChildByType(getTokenElementType(STLexer.RDELIM), ldelim);

                if (rdelim != null) {
                    // use a white/dark background instead of the default green from injected languages
                    holder.createInfoAnnotation(TextRange.create(ldelim.getStartOffset(), rdelim.getStartOffset() + rdelim.getTextLength()), null)
                            .setTextAttributes(ST_TAG);
                }
            }
        }
    }

    private boolean isSubtemplate(@NotNull PsiElement element) {
// Path: src/main/java/org/antlr/jetbrains/st4plugin/psi/STTokenTypes.java
// public class STTokenTypes {
// 
//     private static final List<TokenIElementType> TOKEN_ELEMENT_TYPES = PSIElementTypeFactory.getTokenIElementTypes(STLanguage.INSTANCE);
//     private static final List<RuleIElementType> RULE_ELEMENT_TYPES = PSIElementTypeFactory.getRuleIElementTypes(STLanguage.INSTANCE);
// 
//     public static RuleIElementType getRuleElementType(@MagicConstant(valuesFromClass = STParser.class) int ruleIndex) {
//         return RULE_ELEMENT_TYPES.get(ruleIndex);
//     }
// 
//     public static TokenIElementType getTokenElementType(@MagicConstant(valuesFromClass = STLexer.class) int ruleIndex) {
//         return TOKEN_ELEMENT_TYPES.get(ruleIndex);
//     }
// }
// 
// Path: src/main/java/org/antlr/jetbrains/st4plugin/psi/STTokenTypes.java
// public static RuleIElementType getRuleElementType(@MagicConstant(valuesFromClass = STParser.class) int ruleIndex) {
//     return RULE_ELEMENT_TYPES.get(ruleIndex);
// }
// 
// Path: src/main/java/org/antlr/jetbrains/st4plugin/psi/STTokenTypes.java
// public static TokenIElementType getTokenElementType(@MagicConstant(valuesFromClass = STLexer.class) int ruleIndex) {
//     return TOKEN_ELEMENT_TYPES.get(ruleIndex);
// }


// Path: src/main/java/org/antlr/jetbrains/st4plugin/highlight/STSemanticHighlightAnnotator.java
import com.intellij.lang.ASTNode;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import org.antlr.jetbrains.st4plugin.parsing.STLexer;
import org.antlr.jetbrains.st4plugin.parsing.STParser;
import org.antlr.jetbrains.st4plugin.psi.STTokenTypes;
import org.jetbrains.annotations.NotNull;
import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey;
import static org.antlr.jetbrains.st4plugin.psi.STTokenTypes.getRuleElementType;
import static org.antlr.jetbrains.st4plugin.psi.STTokenTypes.getTokenElementType;

                        .setTextAttributes(STGroupSemanticHighlightAnnotator.TEMPLATE_PARAM);
            } else if (isOptionId(element)) {
                holder.createInfoAnnotation(element, null)
                        .setTextAttributes(OPTION);
            } else if (isCall(element)) {
                holder.createInfoAnnotation(element, null)
                        .setTextAttributes(STGroupSyntaxHighlighter.TEMPLATE_NAME);
            }
        }

        if (isTag(element)) {
            // use a white/dark background instead of the default green from injected languages
            holder.createInfoAnnotation(element, null)
                    .setTextAttributes(ST_TAG);
        }

        if (element.getNode().getElementType() == getRuleElementType(STParser.RULE_ifstat)) {
            for (ASTNode ldelim : element.getNode().getChildren(TokenSet.create(getTokenElementType(STLexer.LDELIM)))) {
                ASTNode rdelim = element.getNode().findChildByType(getTokenElementType(STLexer.RDELIM), ldelim);

                if (rdelim != null) {
                    // use a white/dark background instead of the default green from injected languages
                    holder.createInfoAnnotation(TextRange.create(ldelim.getStartOffset(), rdelim.getStartOffset() + rdelim.getTextLength()), null)
                            .setTextAttributes(ST_TAG);
                }
            }
        }
    }

    private boolean isSubtemplate(@NotNull PsiElement element) {
        return element.getParent().getNode().getElementType() == getRuleElementType(STParser.RULE_subtemplate);