/*
* 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.st4.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 TemplateHighlighterLexer implements TokenSourceWithStateV4<TemplateHighlighterLexerState> {
private static final Map<TemplateHighlighterLexerState, TemplateHighlighterLexerState> sharedStates =
new HashMap<>();
private final GroupHighlighterLexer groupLexer;
@SuppressWarnings("OverridableMethodCallInConstructor")
public TemplateHighlighterLexer(CharStream input, TemplateHighlighterLexerState state) {
this.groupLexer = new GroupHighlighterLexer(input, state.getOpenDelimiter(), state.getCloseDelimiter());
setState(input, state);
}
@Override
public String getSourceName() {
return "StringTemplate Highlighter";
}
@Override
public TemplateHighlighterLexerState getCurrentState() {
if (groupLexer._modeStack == null) {
return getCachedState(groupLexer.getOpenDelimiter(), groupLexer.getCloseDelimiter(), groupLexer._mode, null);
}
return getCachedState(groupLexer.getOpenDelimiter(), groupLexer.getCloseDelimiter(), groupLexer._mode, groupLexer._modeStack.toArray());
}
@Override
public void close() {
// TODO: return this lexer to the lexer cache
}
private static TemplateHighlighterLexerState getCachedState(char openDelimiter, char closeDelimiter, int mode, int[] modeStack) {
TemplateHighlighterLexerState state = new TemplateHighlighterLexerState(openDelimiter, closeDelimiter, mode, modeStack);
synchronized (sharedStates) {
TemplateHighlighterLexerState cached = sharedStates.get(state);
if (cached != null) {
return cached;
}
sharedStates.put(state, state);
return state;
}
}
public void setState(CharStream input, TemplateHighlighterLexerState state) {
groupLexer.setInputStream(input);
groupLexer._mode = state.getMode();
groupLexer._modeStack.clear();
if (state.getModeStack() != null && state.getModeStack().length > 0) {
groupLexer._modeStack.addAll(state.getModeStack());
}
groupLexer.setDelimiters(state.getOpenDelimiter(), state.getCloseDelimiter());
}
@Override
public Token nextToken() {
Token token;
do {
token = nextTokenCore();
} while (token == null || token.getType() == GroupHighlighterLexer.NEWLINE);
return token;
}
private Token nextTokenCore() {
return groupLexer.nextToken();
}
@Override
public int getLine() {
return groupLexer.getLine();
}
@Override
public int getCharPositionInLine() {
return groupLexer.getCharPositionInLine();
}
@Override
public CharStream getInputStream() {
return groupLexer.getInputStream();
}
@Override
public TokenFactory getTokenFactory() {
return groupLexer.getTokenFactory();
}
@Override
public void setTokenFactory(TokenFactory tokenFactory) {
groupLexer.setTokenFactory(tokenFactory);
}
}