/* * Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.antlr.works.editor.grammar.highlighter; import java.util.HashMap; import java.util.Map; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.TokenFactory; import org.antlr.works.editor.antlr4.highlighting.TokenSourceWithStateV4; /** * * @author Sam Harwell */ public class GrammarHighlighterLexerWrapper implements TokenSourceWithStateV4<GrammarHighlighterLexerState> { private static final Map<GrammarHighlighterLexerState, GrammarHighlighterLexerState> sharedStates = new HashMap<>(); private final GrammarHighlighterLexer grammarLexer; @SuppressWarnings("OverridableMethodCallInConstructor") public GrammarHighlighterLexerWrapper(CharStream input, GrammarHighlighterLexerState state) { this.grammarLexer = new GrammarHighlighterLexer(input); setState(input, state); } public GrammarHighlighterLexer getLexer() { return grammarLexer; } @Override public String getSourceName() { return "Grammar Highlighter"; } @Override public GrammarHighlighterLexerState getCurrentState() { if (grammarLexer._modeStack == null) { return getCachedState(grammarLexer.isInOptions(), grammarLexer.isInTokens(), grammarLexer.getRuleType(), grammarLexer._mode, null); } return getCachedState(grammarLexer.isInOptions(), grammarLexer.isInTokens(), grammarLexer.getRuleType(), grammarLexer._mode, grammarLexer._modeStack.toArray()); } @Override public void close() { // this lexer uses the normal shared ATN so there's need to do something special here } private static GrammarHighlighterLexerState getCachedState(boolean inOptions, boolean inTokens, int ruleType, int mode, int[] modeStack) { GrammarHighlighterLexerState state = new GrammarHighlighterLexerState(inOptions, inTokens, ruleType, mode, modeStack); synchronized (sharedStates) { GrammarHighlighterLexerState cached = sharedStates.get(state); if (cached != null) { return cached; } sharedStates.put(state, state); return state; } } public void setState(CharStream input, GrammarHighlighterLexerState state) { grammarLexer.setInputStream(input); grammarLexer._mode = state.getMode(); grammarLexer.setInOptions(state.isInOptions()); grammarLexer.setInTokens(state.isInTokens()); grammarLexer.setRuleType(state.getRuleType()); grammarLexer._modeStack.clear(); if (state.getModeStack() != null && state.getModeStack().length > 0) { grammarLexer._modeStack.addAll(state.getModeStack()); } } @Override public Token nextToken() { Token token; do { token = nextTokenCore(); } while (token == null || token.getType() == GrammarHighlighterLexer.NEWLINE); return token; } private Token nextTokenCore() { return grammarLexer.nextToken(); } @Override public int getLine() { return grammarLexer.getLine(); } @Override public int getCharPositionInLine() { return grammarLexer.getCharPositionInLine(); } @Override public CharStream getInputStream() { return grammarLexer.getInputStream(); } @Override public TokenFactory getTokenFactory() { return grammarLexer.getTokenFactory(); } @Override public void setTokenFactory(TokenFactory tokenFactory) { grammarLexer.setTokenFactory(tokenFactory); } }