package com.babel17.netbeans;
import org.antlr.runtime.CharStream;
import org.netbeans.spi.lexer.LexerInput;
import java.util.*;
/**
* @author jonny
*/
public class AntlrCharStream implements CharStream {
private class CharStreamState {
int index;
int line;
int charPositionInLine;
}
private int line = 1;
private int charPositionInLine = 0;
private LexerInput input;
private String name;
private int index = 0;
private List<CharStreamState> markers;
private int markDepth = 0;
private int lastMarker;
public AntlrCharStream(LexerInput input, String name) {
this.input = input;
this.name = name;
}
public String substring(int start, int stop) {
throw new UnsupportedOperationException("Not supported yet.");
}
public int LT(int i) {
return LA(i);
}
public int getLine() {
return line;
}
public void setLine(int line) {
this.line = line;
}
public void setCharPositionInLine(int pos) {
this.charPositionInLine = pos;
}
public int getCharPositionInLine() {
return charPositionInLine;
}
public void consume() {
int c = input.read();
index++;
charPositionInLine++;
if (c == '\n') {
line++;
charPositionInLine = 0;
}
}
public int LA(int i) {
if (i == 0) {
return 0; // undefined
}
int c = 0;
for (int j = 0; j < i; j++) {
c = read();
}
backup(i);
return c;
}
public int mark() {
if (markers == null) {
markers = new ArrayList<CharStreamState>();
markers.add(null); // depth 0 means no backtracking, leave blank
}
markDepth++;
CharStreamState state = null;
if (markDepth >= markers.size()) {
state = new CharStreamState();
markers.add(state);
} else {
state = markers.get(markDepth);
}
state.index = index;
state.line = line;
state.charPositionInLine = charPositionInLine;
lastMarker = markDepth;
return markDepth;
}
public void rewind() {
rewind(lastMarker);
}
public void rewind(int marker) {
CharStreamState state = markers.get(marker);
// restore stream state
seek(state.index);
line = state.line;
charPositionInLine = state.charPositionInLine;
release(marker);
}
public void release(int marker) {
// unwind any other markers made after m and release m
markDepth = marker;
// release this marker
markDepth--;
}
public void seek(int index) {
if (index < this.index) {
backup(this.index - index);
this.index = index; // just jump; don't update stream state (line, ...)
return;
}
// seek forward, consume until p hits index
while (this.index < index) {
consume();
}
}
public int index() {
return index;
}
public int size() {
return -1; //unknown...
}
public String getSourceName() {
return name;
}
private int read() {
int result = input.read();
if (result == LexerInput.EOF) {
result = CharStream.EOF;
}
return result;
}
private void backup(int count) {
input.backup(count);
}
}