// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package net.starlark.java.syntax;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/** A scanner for Starlark. */
final class Lexer {

  // We intern identifiers and keywords to avoid retaining redundant String objects via the AST.
  //
  // The parser handles interning of string literal values. Benchmarking did not show significant
  // benefit to any further internment. See discussion on Google-internal cl/385193833 for details.
  private static final Interner<String> identInterner = Interners.newWeakInterner();

  // --- These fields are accessed directly by the parser: ---

  // Mapping from file offsets to Locations.
  final FileLocations locs;

  // Information about current token. Updated by nextToken.
  // raw and value are defined only for STRING, INT, FLOAT, IDENTIFIER, and COMMENT.
  // TODO(adonovan): rename s/xyz/tokenXyz/
  TokenKind kind;
  int start; // start offset
  int end; // end offset
  Object value; // String, Integer/Long/BigInteger, or Double value of token

  // --- end of parser-visible fields ---

  private final List<SyntaxError> errors;

  private final FileOptions options;

  // Input buffer and position
  private final char[] buffer;
  private int pos;

  // The stack of enclosing indentation levels in spaces.
  // The first (outermost) element is always zero.
  private final Stack<Integer> indentStack = new Stack<>();

  private final ImmutableList.Builder<Comment> comments = ImmutableList.builder();

  // The number of unclosed open-parens ("(", '{', '[') at the current point in
  // the stream. Whitespace is handled differently when this is nonzero.
  private int openParenStackDepth = 0;

  // True after a NEWLINE token. In other words, we are outside an
  // expression and we have to check the indentation.
  private boolean checkIndentation;

  // Number of saved INDENT (>0) or OUTDENT (<0) tokens detected but not yet returned.
  private int dents;

  // Characters that can come immediately prior to an '=' character to generate
  // a different token
  private static final ImmutableMap<Character, TokenKind> EQUAL_TOKENS =
      ImmutableMap.<Character, TokenKind>builder()
          .put('=', TokenKind.EQUALS_EQUALS)
          .put('!', TokenKind.NOT_EQUALS)
          .put('>', TokenKind.GREATER_EQUALS)
          .put('<', TokenKind.LESS_EQUALS)
          .put('+', TokenKind.PLUS_EQUALS)
          .put('-', TokenKind.MINUS_EQUALS)
          .put('*', TokenKind.STAR_EQUALS)
          .put('/', TokenKind.SLASH_EQUALS)
          .put('%', TokenKind.PERCENT_EQUALS)
          .put('^', TokenKind.CARET_EQUALS)
          .put('&', TokenKind.AMPERSAND_EQUALS)
          .put('|', TokenKind.PIPE_EQUALS)
          .buildOrThrow();

  // Constructs a lexer which tokenizes the parser input.
  // Errors are appended to errors.
  Lexer(ParserInput input, List<SyntaxError> errors, FileOptions options) {
    this.locs = FileLocations.create(input.getContent(), input.getFile());
    this.buffer = input.getContent();
    this.pos = 0;
    this.errors = errors;
    this.options = options;
    this.checkIndentation = true;
    this.dents = 0;

    indentStack.push(0);
  }

  ImmutableList<Comment> getComments() {
    return comments.build();
  }

  /**
   * Reads the next token, updating the Lexer's token fields. It is an error to call nextToken after
   * an EOF token.
   */
  void nextToken() {
    boolean afterNewline = kind == TokenKind.NEWLINE;
    tokenize();
    Preconditions.checkState(kind != null);

    // Like Python, always end with a NEWLINE token, even if no '\n' in input:
    if (kind == TokenKind.EOF && !afterNewline) {
      kind = TokenKind.NEWLINE;
    }
  }

  private void popParen() {
    if (openParenStackDepth == 0) {
      // TODO(adonovan): fix: the input ')' should not report an indentation error.
      error("indentation error", pos - 1);
    } else {
      openParenStackDepth--;
    }
  }

  private void error(String message, int pos) {
    errors.add(new SyntaxError(locs.getLocation(pos), message));
  }

  private void setToken(TokenKind kind, int start, int end) {
    this.kind = kind;
    this.start = start;
    this.end = end;
    this.value = null;
  }

  // setValue sets the value associated with a STRING, FLOAT, INT,
  // IDENTIFIER, or COMMENT token, and records the raw text of the token.
  private void setValue(Object value) {
    this.value = value;
  }

  /** Returns the raw input text associated with the current token. */
  String getRaw() {
    return bufferSlice(start, end);
  }

  /**
   * Parses an end-of-line sequence, handling statement indentation correctly.
   *
   * <p>UNIX newlines are assumed (LF). Carriage returns are always ignored.
   */
  private void newline() {
    if (openParenStackDepth > 0) {
      newlineInsideExpression(); // in an expression: ignore space
    } else {
      checkIndentation = true;
      setToken(TokenKind.NEWLINE, pos - 1, pos);
    }
  }

  private void newlineInsideExpression() {
    while (pos < buffer.length) {
      switch (buffer[pos]) {
        case ' ': case '\t': case '\r':
          pos++;
          break;
        default:
          return;
      }
    }
  }

  /** Computes indentation (updates dent) and advances pos. */
  private void computeIndentation() {
    // we're in a stmt: suck up space at beginning of next line
    int indentLen = 0;
    while (pos < buffer.length) {
      char c = buffer[pos];
      if (c == ' ') {
        indentLen++;
        pos++;
      } else if (c == '\r') {
        pos++;
      } else if (c == '\t') {
        indentLen++;
        pos++;
        error("Tab characters are not allowed for indentation. Use spaces instead.", pos);
      } else if (c == '\n') { // entirely blank line: discard
        indentLen = 0;
        pos++;
      } else if (c == '#') { // line containing only indented comment
        int oldPos = pos;
        while (pos < buffer.length && c != '\n') {
          c = buffer[pos++];
        }
        addComment(oldPos, pos - 1);
        indentLen = 0;
      } else { // printing character
        break;
      }
    }

    if (pos == buffer.length) {
      indentLen = 0;
    } // trailing space on last line

    int peekedIndent = indentStack.peek();
    if (peekedIndent < indentLen) { // push a level
      indentStack.push(indentLen);
      dents++;

    } else if (peekedIndent > indentLen) { // pop one or more levels
      while (peekedIndent > indentLen) {
        indentStack.pop();
        dents--;
        peekedIndent = indentStack.peek();
      }

      if (peekedIndent < indentLen) {
        error("indentation error", pos - 1);
      }
    }
  }

  /**
   * Returns true if current position is in the middle of a triple quote
   * delimiter (3 x quot), and advances 'pos' by two if so.
   */
  private boolean skipTripleQuote(char quot) {
    if (peek(0) == quot && peek(1) == quot) {
      pos += 2;
      return true;
    } else {
      return false;
    }
  }

  /**
   * Scans a string literal delimited by 'quot', containing escape sequences.
   *
   * <p>ON ENTRY: 'pos' is 1 + the index of the first delimiter
   * ON EXIT: 'pos' is 1 + the index of the last delimiter.
   */
  private void escapedStringLiteral(char quot, boolean isRaw) {
    int literalStartPos = isRaw ? pos - 2 : pos - 1;
    boolean inTriplequote = skipTripleQuote(quot);
    // more expensive second choice that expands escaped into a buffer
    StringBuilder literal = new StringBuilder();
    while (pos < buffer.length) {
      char c = buffer[pos];
      pos++;
      switch (c) {
        case '\n':
          if (inTriplequote) {
            literal.append(c);
            break;
          } else {
            error("unclosed string literal", literalStartPos);
            setToken(TokenKind.STRING, literalStartPos, pos);
            setValue(literal.toString());
            return;
          }
        case '\\':
          if (pos == buffer.length) {
            error("unclosed string literal", literalStartPos);
            setToken(TokenKind.STRING, literalStartPos, pos);
            setValue(literal.toString());
            return;
          }
          if (isRaw) {
            // Insert \ and the following character.
            // As in Python, it means that a raw string can never end with a single \.
            literal.append('\\');
            if (peek(0) == '\r' && peek(1) == '\n') {
              literal.append("\n");
              pos += 2;
            } else if (buffer[pos] == '\r' || buffer[pos] == '\n') {
              literal.append("\n");
              pos += 1;
            } else {
              literal.append(buffer[pos]);
              pos += 1;
            }
            break;
          }
          c = buffer[pos];
          pos++;
          switch (c) {
            case '\r':
              if (peek(0) == '\n') {
                pos += 1;
                break;
              } else {
                break;
              }
            case '\n':
              // ignore end of line character
              break;
            case 'a':
              literal.append('\u0007');
              break;
            case 'b':
              literal.append('\b');
              break;
            case 'f':
              literal.append('\f');
              break;
            case 'n':
              literal.append('\n');
              break;
            case 'r':
              literal.append('\r');
              break;
            case 't':
              literal.append('\t');
              break;
            case 'v':
              literal.append('\u000b');
              break;
            case '\\':
              literal.append('\\');
              break;
            case '\'':
              literal.append('\'');
              break;
            case '"':
              literal.append('"');
              break;
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
              { // octal escape
                int octal = c - '0';
                if (pos < buffer.length) {
                  c = buffer[pos];
                  if (c >= '0' && c <= '7') {
                    pos++;
                    octal = (octal << 3) | (c - '0');
                    if (pos < buffer.length) {
                      c = buffer[pos];
                      if (c >= '0' && c <= '7') {
                        pos++;
                        octal = (octal << 3) | (c - '0');
                      }
                    }
                  }
                }
                if (octal > 0xff) {
                  error("octal escape sequence out of range (maximum is \\377)", pos - 1);
                } else if (options.stringLiteralsAreAsciiOnly() && octal >= 0x80) {
                  error("octal escape sequence denotes non-ASCII character", pos - 1);
                }
                literal.append((char) (octal & 0xff));
                break;
              }
            case 'N':
            case 'u':
            case 'U':
            default:
              // unknown char escape => "\literal"
              error("invalid escape sequence: \\" + c + ". Use '\\\\' to insert '\\'.", pos - 1);
              literal.append('\\');
              literal.append(c);
              break;
          }
          break;
        case '\'':
        case '"':
          if (c != quot || (inTriplequote && !skipTripleQuote(quot))) {
            // Non-matching quote, treat it like a regular char.
            literal.append(c);
          } else {
            // Matching close-delimiter, all done.
            setToken(TokenKind.STRING, literalStartPos, pos);
            setValue(literal.toString());
            return;
          }
          break;
        default:
          literal.append(c);
          if (options.stringLiteralsAreAsciiOnly() && c >= 0x80) {
            error("string literal contains non-ASCII character", pos - 1);
          }
          break;
      }
    }
    error("unclosed string literal", literalStartPos);
    setToken(TokenKind.STRING, literalStartPos, pos);
    setValue(literal.toString());
  }

  /**
   * Scans a string literal delimited by 'quot'.
   *
   * <ul>
   * <li> ON ENTRY: 'pos' is 1 + the index of the first delimiter
   * <li> ON EXIT: 'pos' is 1 + the index of the last delimiter.
   * </ul>
   *
   * @param isRaw if true, do not escape the string.
   */
  private void stringLiteral(char quot, boolean isRaw) {
    int literalStartPos = isRaw ? pos - 2 : pos - 1;
    int contentStartPos = pos;

    // Don't even attempt to parse triple-quotes here.
    if (skipTripleQuote(quot)) {
      pos -= 2;
      escapedStringLiteral(quot, isRaw);
      return;
    }

    // first quick optimistic scan for a simple non-escaped string
    while (pos < buffer.length) {
      char c = buffer[pos++];
      switch (c) {
        case '\n':
          error("unclosed string literal", literalStartPos);
          setToken(TokenKind.STRING, literalStartPos, pos);
          setValue(bufferSlice(contentStartPos, pos - 1));
          return;
        case '\\':
          if (isRaw) {
            if (peek(0) == '\r' && peek(1) == '\n') {
              // There was a CRLF after the newline. No shortcut possible, since it needs to be
              // transformed into a single LF.
              pos = contentStartPos;
              escapedStringLiteral(quot, true);
              return;
            } else {
              pos++;
              break;
            }
          }
          // oops, hit an escape, need to start over & build a new string buffer
          pos = contentStartPos;
          escapedStringLiteral(quot, false);
          return;
        case '\'':
        case '"':
          if (c == quot) {
            // close-quote, all done.
            setToken(TokenKind.STRING, literalStartPos, pos);
            setValue(bufferSlice(contentStartPos, pos - 1));
            // If we're requiring ASCII-only, do another scan for validation.
            if (options.stringLiteralsAreAsciiOnly()) {
              for (int i = contentStartPos; i < pos - 1; i++) {
                if (buffer[i] >= 0x80) {
                  // Can report multiple errors per string literal.
                  error("string literal contains non-ASCII character", i);
                }
              }
            }
            return;
          }
          break;
        default: // fall out
      }
    }

    // If the current position is beyond the end of the file, need to move it backwards
    // Possible if the file ends with `r"\` (unclosed raw string literal with a backslash)
    if (pos > buffer.length) {
      pos = buffer.length;
    }

    error("unclosed string literal", literalStartPos);
    setToken(TokenKind.STRING, literalStartPos, pos);
    setValue(bufferSlice(contentStartPos, pos));
  }

  private static final Map<String, TokenKind> keywordMap = new HashMap<>();

  static {
    keywordMap.put("and", TokenKind.AND);
    keywordMap.put("as", TokenKind.AS);
    keywordMap.put("assert", TokenKind.ASSERT);
    keywordMap.put("break", TokenKind.BREAK);
    keywordMap.put("class", TokenKind.CLASS);
    keywordMap.put("continue", TokenKind.CONTINUE);
    keywordMap.put("def", TokenKind.DEF);
    keywordMap.put("del", TokenKind.DEL);
    keywordMap.put("elif", TokenKind.ELIF);
    keywordMap.put("else", TokenKind.ELSE);
    keywordMap.put("except", TokenKind.EXCEPT);
    keywordMap.put("finally", TokenKind.FINALLY);
    keywordMap.put("for", TokenKind.FOR);
    keywordMap.put("from", TokenKind.FROM);
    keywordMap.put("global", TokenKind.GLOBAL);
    keywordMap.put("if", TokenKind.IF);
    keywordMap.put("import", TokenKind.IMPORT);
    keywordMap.put("in", TokenKind.IN);
    keywordMap.put("is", TokenKind.IS);
    keywordMap.put("lambda", TokenKind.LAMBDA);
    keywordMap.put("load", TokenKind.LOAD);
    keywordMap.put("nonlocal", TokenKind.NONLOCAL);
    keywordMap.put("not", TokenKind.NOT);
    keywordMap.put("or", TokenKind.OR);
    keywordMap.put("pass", TokenKind.PASS);
    keywordMap.put("raise", TokenKind.RAISE);
    keywordMap.put("return", TokenKind.RETURN);
    keywordMap.put("try", TokenKind.TRY);
    keywordMap.put("while", TokenKind.WHILE);
    keywordMap.put("with", TokenKind.WITH);
    keywordMap.put("yield", TokenKind.YIELD);
  }

  /**
   * Scans an identifier or keyword.
   *
   * <p>ON ENTRY: 'pos' is 1 + the index of the first char in the identifier.
   * ON EXIT: 'pos' is 1 + the index of the last char in the identifier.
   */
  private void identifierOrKeyword() {
    int oldPos = pos - 1;
    String id = identInterner.intern(scanIdentifier());
    TokenKind kind = keywordMap.get(id);
    if (kind == null) {
      setToken(TokenKind.IDENTIFIER, oldPos, pos);
      // setValue allocates a new String for the raw text, but it's not retained so we don't bother
      // interning it.
      setValue(id);
    } else {
      setToken(kind, oldPos, pos);
    }
  }

  private String scanIdentifier() {
    // Keep consistent with Identifier.isValid.
    // TODO(laurentlb): Handle Unicode letters.
    int oldPos = pos - 1;
    while (pos < buffer.length) {
      switch (buffer[pos]) {
        case '_':
        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
        case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
        case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
        case 's': case 't': case 'u': case 'v': case 'w': case 'x':
        case 'y': case 'z':
        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
        case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
        case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
        case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
        case 'Y': case 'Z':
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9':
          pos++;
          break;
       default:
          return bufferSlice(oldPos, pos);
      }
    }
    return bufferSlice(oldPos, pos);
  }

  /**
   * Tokenizes a two-char operator.
   * @return true if it tokenized an operator
   */
  private boolean tokenizeTwoChars() {
    if (pos + 2 >= buffer.length) {
      return false;
    }
    char c1 = buffer[pos];
    char c2 = buffer[pos + 1];
    TokenKind tok = null;
    if (c2 == '=') {
      tok = EQUAL_TOKENS.get(c1);
    } else if (c2 == '*' && c1 == '*') {
      tok = TokenKind.STAR_STAR;
    }
    if (tok == null) {
      return false;
    } else {
      setToken(tok, pos, pos + 2);
      return true;
    }
  }

  // Returns the ith unconsumed char, or -1 for EOF.
  private int peek(int i) {
    return pos + i < buffer.length ? buffer[pos + i] : -1;
  }

  // Consumes a char and returns the next unconsumed char, or -1 for EOF.
  private int next() {
    pos++;
    return peek(0);
  }

  /**
   * Performs tokenization of the character buffer of file contents provided to the constructor. At
   * least one token will be added to the tokens queue.
   */
  private void tokenize() {
    if (checkIndentation) {
      checkIndentation = false;
      computeIndentation();
    }

    // Return saved indentation tokens.
    if (dents != 0) {
      if (dents < 0) {
        dents++;
        setToken(TokenKind.OUTDENT, pos - 1, pos);
      } else {
        dents--;
        setToken(TokenKind.INDENT, pos - 1, pos);
      }
      return;
    }

    // TODO(adonovan): cleanup: replace break after setToken with return,
    // and eliminate null-check of this.kind.
    kind = null;
    while (pos < buffer.length) {
      if (tokenizeTwoChars()) {
        pos += 2;
        return;
      }
      char c = buffer[pos];
      pos++;
      switch (c) {
        case '{':
          setToken(TokenKind.LBRACE, pos - 1, pos);
          openParenStackDepth++;
          break;
        case '}':
          setToken(TokenKind.RBRACE, pos - 1, pos);
          popParen();
          break;
        case '(':
          setToken(TokenKind.LPAREN, pos - 1, pos);
          openParenStackDepth++;
          break;
        case ')':
          setToken(TokenKind.RPAREN, pos - 1, pos);
          popParen();
          break;
        case '[':
          setToken(TokenKind.LBRACKET, pos - 1, pos);
          openParenStackDepth++;
          break;
        case ']':
          setToken(TokenKind.RBRACKET, pos - 1, pos);
          popParen();
          break;
        case '>':
          if (peek(0) == '>' && peek(1) == '=') {
            setToken(TokenKind.GREATER_GREATER_EQUALS, pos - 1, pos + 2);
            pos += 2;
          } else if (peek(0) == '>') {
            setToken(TokenKind.GREATER_GREATER, pos - 1, pos + 1);
            pos += 1;
          } else {
            setToken(TokenKind.GREATER, pos - 1, pos);
          }
          break;
        case '<':
          if (peek(0) == '<' && peek(1) == '=') {
            setToken(TokenKind.LESS_LESS_EQUALS, pos - 1, pos + 2);
            pos += 2;
          } else if (peek(0) == '<') {
            setToken(TokenKind.LESS_LESS, pos - 1, pos + 1);
            pos += 1;
          } else {
            setToken(TokenKind.LESS, pos - 1, pos);
          }
          break;
        case ':':
          setToken(TokenKind.COLON, pos - 1, pos);
          break;
        case ',':
          setToken(TokenKind.COMMA, pos - 1, pos);
          break;
        case '+':
          setToken(TokenKind.PLUS, pos - 1, pos);
          break;
        case '-':
          setToken(TokenKind.MINUS, pos - 1, pos);
          break;
        case '|':
          setToken(TokenKind.PIPE, pos - 1, pos);
          break;
        case '=':
          setToken(TokenKind.EQUALS, pos - 1, pos);
          break;
        case '%':
          setToken(TokenKind.PERCENT, pos - 1, pos);
          break;
        case '~':
          setToken(TokenKind.TILDE, pos - 1, pos);
          break;
        case '&':
          setToken(TokenKind.AMPERSAND, pos - 1, pos);
          break;
        case '^':
          setToken(TokenKind.CARET, pos - 1, pos);
          break;
        case '/':
          if (peek(0) == '/' && peek(1) == '=') {
            setToken(TokenKind.SLASH_SLASH_EQUALS, pos - 1, pos + 2);
            pos += 2;
          } else if (peek(0) == '/') {
            setToken(TokenKind.SLASH_SLASH, pos - 1, pos + 1);
            pos += 1;
          } else {
            // /= is handled by tokenizeTwoChars.
            setToken(TokenKind.SLASH, pos - 1, pos);
          }
          break;
        case ';':
          setToken(TokenKind.SEMI, pos - 1, pos);
          break;
        case '*':
          setToken(TokenKind.STAR, pos - 1, pos);
          break;
        case ' ':
        case '\t':
        case '\r':
          /* ignore */
          break;
        case '\\':
          // Backslash character is valid only at the end of a line (or in a string)
          if (peek(0) == '\n') {
            pos += 1; // skip the end of line character
          } else if (peek(0) == '\r' && peek(1) == '\n') {
            pos += 2; // skip the CRLF at the end of line
          } else {
            setToken(TokenKind.ILLEGAL, pos - 1, pos);
            setValue(Character.toString(c));
          }
          break;
        case '\n':
          newline();
          break;
        case '#':
          int oldPos = pos - 1;
          while (pos < buffer.length) {
            c = buffer[pos];
            if (c == '\n') {
              break;
            } else {
              pos++;
            }
          }
          addComment(oldPos, pos);
          break;
        case '\'':
        case '\"':
          stringLiteral(c, false);
          break;
        default:
          // detect raw strings, e.g. r"str"
          if (c == 'r') {
            int c0 = peek(0);
            if (c0 == '\'' || c0 == '\"') {
              pos++;
              stringLiteral((char) c0, true);
              break;
            }
          }

          // int or float literal, or dot
          if (c == '.' || isdigit(c)) {
            pos--; // unconsume
            scanNumberOrDot(c);
            break;
          }

          if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
            identifierOrKeyword();
          } else {
            error("invalid character: '" + c + "'", pos - 1);
          }
          break;
      } // switch
      if (kind != null) { // stop here if we scanned a token
        return;
      }
    } // while

    if (indentStack.size() > 1) { // top of stack is always zero
      setToken(TokenKind.NEWLINE, pos - 1, pos);
      while (indentStack.size() > 1) {
        indentStack.pop();
        dents--;
      }
      return;
    }

    setToken(TokenKind.EOF, pos, pos);
  }

  // Scans a number (INT or FLOAT) or DOT.
  // Precondition: c == peek(0) (a dot or digit)
  //
  // TODO(adonovan): make this the precondition for all scan functions;
  // currenly most assume their argument c has been consumed already.
  private void scanNumberOrDot(int c) {
    int start = this.pos;
    boolean fraction = false;
    boolean exponent = false;

    if (c == '.') {
      // dot or start of fraction
      if (!isdigit(peek(1))) {
        pos++; // consume '.'
        setToken(TokenKind.DOT, start, pos);
        return;
      }
      fraction = true;

    } else if (c == '0') {
      // hex, octal, binary or float
      c = next();
      if (c == '.') {
        fraction = true;

      } else if (c == 'x' || c == 'X') {
        // hex
        c = next();
        if (!isxdigit(c)) {
          error("invalid hex literal", start);
        }
        while (isxdigit(c)) {
          c = next();
        }

      } else if (c == 'o' || c == 'O') {
        // octal
        c = next();
        while (isdigit(c)) {
          c = next();
        }

      } else if (c == 'b' || c == 'B') {
        // binary
        c = next();
        if (!isbdigit(c)) {
          error("invalid binary literal", start);
        }
        while (isbdigit(c)) {
          c = next();
        }

      } else {
        // "0" or float or obsolete octal "0755"
        while (isdigit(c)) {
          c = next();
        }
        if (c == '.') {
          fraction = true;
        } else if (c == 'e' || c == 'E') {
          exponent = true;
        }
      }

    } else {
      // decimal
      while (isdigit(c)) {
        c = next();
      }
      if (c == '.') {
        fraction = true;
      } else if (c == 'e' || c == 'E') {
        exponent = true;
      }
    }

    if (fraction) {
      c = next(); // consume '.'
      while (isdigit(c)) {
        c = next();
      }

      if (c == 'e' || c == 'E') {
        exponent = true;
      }
    }

    if (exponent) {
      c = next(); // consume [eE]
      if (c == '+' || c == '-') {
        c = next();
      }
      while (isdigit(c)) {
        c = next();
      }
    }

    // float?
    if (fraction || exponent) {
      setToken(TokenKind.FLOAT, start, pos);
      double value = 0.0;
      try {
        value = Double.parseDouble(bufferSlice(start, pos));
        if (!Double.isFinite(value)) {
          error("floating-point literal too large", start);
        }
      } catch (NumberFormatException ex) {
        error("invalid float literal", start);
      }
      setValue(value);
      return;
    }

    // int
    setToken(TokenKind.INT, start, pos);
    String literal = bufferSlice(start, pos);
    Number value = 0;
    try {
      value = IntLiteral.scan(literal);
    } catch (NumberFormatException ex) {
      error(ex.getMessage(), start);
    }
    setValue(value);
  }

  private static boolean isdigit(int c) {
    return '0' <= c && c <= '9';
  }

  private static boolean isxdigit(int c) {
    return isdigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
  }

  private static boolean isbdigit(int c) {
    return c == '0' || c == '1';
  }

  /*
   * Returns a string containing the part of the source buffer beginning at offset {@code start} and
   * ending immediately before offset {@code end} (so the length of the resulting string is {@code
   * end - start}).
   */
  String bufferSlice(int start, int end) {
    return new String(this.buffer, start, end - start);
  }

  // TODO(adonovan): don't retain comments unconditionally.
  private void addComment(int start, int end) {
    String content = bufferSlice(start, end);
    comments.add(new Comment(locs, start, content));
  }
}
