title: NetBeans platform language and ANTLR lexer
body: <p>How to adapt the NetBeans LexerInput to a CharStream of ANTLR. I have the next implementation, but don't work well. I want to add a new language to the NetBeans platform throught ANTLR lexer.</p>
  
  <p>The Lexer emit only EOF, but the token type is ok, i don't understand.</p>
  
  <p></p>
  
  <pre><code>import java.util.ArrayList;
  import java.util.List;
  import org.antlr.v4.runtime.CharStream;
  import org.antlr.v4.runtime.misc.Interval;
  import org.netbeans.spi.lexer.LexerInput;
  
  /**
   * @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&lt;CharStreamState&gt; markers;
      private int markDepth = 0;
      private int lastMarker;
  
      public AntlrCharStream(LexerInput input, String name) {
          this.input = input;
          this.name = name;
      }
  
      @Override
      public String getText(Interval intrvl) {
          return input.readText().toString();
      }
  
      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 &lt; i; j++) {
              c = read();
          }
          backup(i);
          return c;
      }
  
      public int mark() {
          if (markers == null) {
              markers = new ArrayList&lt;CharStreamState&gt;();
              markers.add(null); // depth 0 means no backtracking, leave blank
          }
          markDepth++;
          CharStreamState state = null;
          if (markDepth &gt;= markers.size()) {
              state = new CharStreamState();
              markers.add(state);
          } else {
              state = (CharStreamState) 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 = (CharStreamState) 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 &lt; 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 &lt; 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);
      }
  }
  </code></pre>
  
  <p></p>
  
  <pre><code>'[@-1,6:6='&lt;EOF&gt;',&lt;1&gt;,2:2]'
  '[@-1,7:7='&lt;EOF&gt;',&lt;1&gt;,2:3]'
  '[@-1,8:15='&lt;EOF&gt;',&lt;9&gt;,2:4]'
  '[@-1,16:16='&lt;EOF&gt;',&lt;1&gt;,2:12]'
  '[@-1,17:23='&lt;EOF&gt;',&lt;8&gt;,2:13]'
  '[@-1,24:24='&lt;EOF&gt;',&lt;1&gt;,2:20]'
  '[@-1,25:25='&lt;EOF&gt;',&lt;2&gt;,2:21]'
  '[@-1,26:26='&lt;EOF&gt;',&lt;1&gt;,3:0]'
  '[@-1,27:27='&lt;EOF&gt;',&lt;1&gt;,3:1]'
  '[@-1,28:28='&lt;EOF&gt;',&lt;1&gt;,3:2]'
  '[@-1,29:29='&lt;EOF&gt;',&lt;1&gt;,3:3]'
  '[@-1,30:37='&lt;EOF&gt;',&lt;4&gt;,3:4]'
  '[@-1,38:38='&lt;EOF&gt;',&lt;1&gt;,3:12]'
  '[@-1,39:43='&lt;EOF&gt;',&lt;5&gt;,3:13]'
  '[@-1,44:44='&lt;EOF&gt;',&lt;1&gt;,3:18]'
  '[@-1,45:48='&lt;EOF&gt;',&lt;9&gt;,3:19]'
  '[@-1,49:49='&lt;EOF&gt;',&lt;1&gt;,3:23]'
  '[@-1,50:53='&lt;EOF&gt;',&lt;7&gt;,3:24]'
  '[@-1,54:54='&lt;EOF&gt;',&lt;1&gt;,3:28]'
  '[@-1,55:56='&lt;EOF&gt;',&lt;6&gt;,3:29]'
  '[@-1,57:57='&lt;EOF&gt;',&lt;2&gt;,3:31]'
  '[@-1,58:57='&lt;EOF&gt;',&lt;-1&gt;,4:32]'
  </code></pre>