/**
* Copyright (C) 2015 drrb
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.drrb.rust.netbeans.parsing;
import com.github.drrb.rust.netbeans.rustbridge.RustToken;
import com.github.drrb.rust.netbeans.rustbridge.RustLexer;
import org.netbeans.api.lexer.Token;
import org.netbeans.spi.lexer.Lexer;
import org.netbeans.spi.lexer.LexerInput;
import org.netbeans.spi.lexer.LexerRestartInfo;
public class NetbeansRustLexer implements Lexer<RustTokenId> {
private static final Token<RustTokenId> EOF_TOKEN = null;
private final LexerRestartInfo<RustTokenId> info;
private RustLexer lexer = RustLexer.NULL_LEXER;
public NetbeansRustLexer(LexerRestartInfo<RustTokenId> info) {
this.info = info;
}
@Override
public Token<RustTokenId> nextToken() {
ensureLexerCreated();
RustToken token = lexer.nextToken();
if (token == null) {
readWholeSource();
return createToken(RustTokenId.GARBAGE);
} else if (token.getType() == RustTokenId.EOF) {
return EOF_TOKEN;
} else {
for (int i = 0; i < token.length(); i++) {
readOneCharacter();
}
if (info.input().readLength() == 0) {
return EOF_TOKEN;
} else {
return createToken(token.getType());
}
}
}
private void ensureLexerCreated() {
if (lexer == RustLexer.NULL_LEXER) {
String source = readWholeSource();
backUp(charsReadThisToken());
lexer = RustLexer.forString(source);
}
}
private String readWholeSource() {
reading: while (readOneCharacter() != LexerInput.EOF) {
continue reading;
}
return charactersReadSoFar();
}
protected void backUp(int length) {
info.input().backup(length);
}
protected int charsReadThisToken() {
return info.input().readLengthEOF();
}
protected String charactersReadSoFar() {
return info.input().readText().toString();
}
protected int readOneCharacter() {
return info.input().read();
}
protected Token<RustTokenId> createToken(RustTokenId tokenType) {
return info.tokenFactory().createToken(tokenType);
}
@Override
public Object state() {
return null;
}
@Override
public void release() {
lexer.release();
}
}