// This code was auto-generated, is not intended to be edited, and is subject to
// significant change. Please see the README file for more information.
library engine.scanner;
import 'dart:collection';
import 'java_core.dart';
import 'java_engine.dart';
import 'source.dart';
import 'error.dart';
import 'instrumentation.dart';
/**
 * Instances of the abstract class `KeywordState` represent a state in a state machine used to
 * scan keywords.
 *
 * @coverage dart.engine.parser
 */
class KeywordState {

  /**
   * An empty transition table used by leaf states.
   */
  static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>(26);

  /**
   * The initial state in the state machine.
   */
  static KeywordState KEYWORD_STATE = createKeywordStateTable();

  /**
   * Create the next state in the state machine where we have already recognized the subset of
   * strings in the given array of strings starting at the given offset and having the given length.
   * All of these strings have a common prefix and the next character is at the given start index.
   *
   * @param start the index of the character in the strings used to transition to a new state
   * @param strings an array containing all of the strings that will be recognized by the state
   *          machine
   * @param offset the offset of the first string in the array that has the prefix that is assumed
   *          to have been recognized by the time we reach the state being built
   * @param length the number of strings in the array that pass through the state being built
   * @return the state that was created
   */
  static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length2) {
    List<KeywordState> result = new List<KeywordState>(26);
    assert(length2 != 0);
    int chunk = 0x0;
    int chunkStart = -1;
    bool isLeaf = false;
    for (int i = offset; i < offset + length2; i++) {
      if (strings[i].length == start) {
        isLeaf = true;
      }
      if (strings[i].length > start) {
        int c = strings[i].codeUnitAt(start);
        if (chunk != c) {
          if (chunkStart != -1) {
            result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, i - chunkStart);
          }
          chunkStart = i;
          chunk = c;
        }
      }
    }
    if (chunkStart != -1) {
      assert(result[chunk - 0x61] == null);
      result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length2 - chunkStart);
    } else {
      assert(length2 == 1);
      return new KeywordState(_EMPTY_TABLE, strings[offset]);
    }
    if (isLeaf) {
      return new KeywordState(result, strings[offset]);
    } else {
      return new KeywordState(result, null);
    }
  }

  /**
   * Create the initial state in the state machine.
   *
   * @return the state that was created
   */
  static KeywordState createKeywordStateTable() {
    List<Keyword> values = Keyword.values;
    List<String> strings = new List<String>(values.length);
    for (int i = 0; i < values.length; i++) {
      strings[i] = values[i].syntax;
    }
    strings.sort();
    return computeKeywordStateTable(0, strings, 0, strings.length);
  }

  /**
   * A table mapping characters to the states to which those characters will transition. (The index
   * into the array is the offset from the character `'a'` to the transitioning character.)
   */
  List<KeywordState> _table;

  /**
   * The keyword that is recognized by this state, or `null` if this state is not a terminal
   * state.
   */
  Keyword _keyword2;

  /**
   * Initialize a newly created state to have the given transitions and to recognize the keyword
   * with the given syntax.
   *
   * @param table a table mapping characters to the states to which those characters will transition
   * @param syntax the syntax of the keyword that is recognized by the state
   */
  KeywordState(List<KeywordState> table, String syntax) {
    this._table = table;
    this._keyword2 = (syntax == null) ? null : Keyword.keywords[syntax];
  }

  /**
   * Return the keyword that was recognized by this state, or `null` if this state does not
   * recognized a keyword.
   *
   * @return the keyword that was matched by reaching this state
   */
  Keyword keyword() => _keyword2;

  /**
   * Return the state that follows this state on a transition of the given character, or
   * `null` if there is no valid state reachable from this state with such a transition.
   *
   * @param c the character used to transition from this state to another state
   * @return the state that follows this state on a transition of the given character
   */
  KeywordState next(int c) => _table[c - 0x61];
}
/**
 * The enumeration `ScannerErrorCode` defines the error codes used for errors detected by the
 * scanner.
 *
 * @coverage dart.engine.parser
 */
class ScannerErrorCode extends Enum<ScannerErrorCode> implements ErrorCode {
  static final ScannerErrorCode CHARACTER_EXPECTED_AFTER_SLASH = new ScannerErrorCode.con1('CHARACTER_EXPECTED_AFTER_SLASH', 0, "Character expected after slash");
  static final ScannerErrorCode ILLEGAL_CHARACTER = new ScannerErrorCode.con1('ILLEGAL_CHARACTER', 1, "Illegal character %x");
  static final ScannerErrorCode MISSING_DIGIT = new ScannerErrorCode.con1('MISSING_DIGIT', 2, "Decimal digit expected");
  static final ScannerErrorCode MISSING_HEX_DIGIT = new ScannerErrorCode.con1('MISSING_HEX_DIGIT', 3, "Hexidecimal digit expected");
  static final ScannerErrorCode MISSING_QUOTE = new ScannerErrorCode.con1('MISSING_QUOTE', 4, "Expected quote (' or \")");
  static final ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT = new ScannerErrorCode.con1('UNTERMINATED_MULTI_LINE_COMMENT', 5, "Unterminated multi-line comment");
  static final ScannerErrorCode UNTERMINATED_STRING_LITERAL = new ScannerErrorCode.con1('UNTERMINATED_STRING_LITERAL', 6, "Unterminated string literal");
  static final List<ScannerErrorCode> values = [
      CHARACTER_EXPECTED_AFTER_SLASH,
      ILLEGAL_CHARACTER,
      MISSING_DIGIT,
      MISSING_HEX_DIGIT,
      MISSING_QUOTE,
      UNTERMINATED_MULTI_LINE_COMMENT,
      UNTERMINATED_STRING_LITERAL];

  /**
   * The template used to create the message to be displayed for this error.
   */
  String _message;

  /**
   * The template used to create the correction to be displayed for this error, or `null` if
   * there is no correction information for this error.
   */
  String correction10;

  /**
   * Initialize a newly created error code to have the given message.
   *
   * @param message the message template used to create the message to be displayed for this error
   */
  ScannerErrorCode.con1(String name, int ordinal, String message) : super(name, ordinal) {
    this._message = message;
  }

  /**
   * Initialize a newly created error code to have the given message and correction.
   *
   * @param message the template used to create the message to be displayed for the error
   * @param correction the template used to create the correction to be displayed for the error
   */
  ScannerErrorCode.con2(String name, int ordinal, String message, String correction) : super(name, ordinal) {
    this._message = message;
    this.correction10 = correction;
  }
  String get correction => correction10;
  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
  String get message => _message;
  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
}
/**
 * Instances of the class `TokenWithComment` represent a string token that is preceded by
 * comments.
 *
 * @coverage dart.engine.parser
 */
class StringTokenWithComment extends StringToken {

  /**
   * The first comment in the list of comments that precede this token.
   */
  Token _precedingComment;

  /**
   * Initialize a newly created token to have the given type and offset and to be preceded by the
   * comments reachable from the given comment.
   *
   * @param type the type of the token
   * @param offset the offset from the beginning of the file to the first character in the token
   * @param precedingComment the first comment in the list of comments that precede this token
   */
  StringTokenWithComment(TokenType type, String value, int offset, Token precedingComment) : super(type, value, offset) {
    this._precedingComment = precedingComment;
  }
  Token get precedingComments => _precedingComment;
}
/**
 * The enumeration `Keyword` defines the keywords in the Dart programming language.
 *
 * @coverage dart.engine.parser
 */
class Keyword extends Enum<Keyword> {
  static final Keyword ASSERT = new Keyword.con1('ASSERT', 0, "assert");
  static final Keyword BREAK = new Keyword.con1('BREAK', 1, "break");
  static final Keyword CASE = new Keyword.con1('CASE', 2, "case");
  static final Keyword CATCH = new Keyword.con1('CATCH', 3, "catch");
  static final Keyword CLASS = new Keyword.con1('CLASS', 4, "class");
  static final Keyword CONST = new Keyword.con1('CONST', 5, "const");
  static final Keyword CONTINUE = new Keyword.con1('CONTINUE', 6, "continue");
  static final Keyword DEFAULT = new Keyword.con1('DEFAULT', 7, "default");
  static final Keyword DO = new Keyword.con1('DO', 8, "do");
  static final Keyword ELSE = new Keyword.con1('ELSE', 9, "else");
  static final Keyword ENUM = new Keyword.con1('ENUM', 10, "enum");
  static final Keyword EXTENDS = new Keyword.con1('EXTENDS', 11, "extends");
  static final Keyword FALSE = new Keyword.con1('FALSE', 12, "false");
  static final Keyword FINAL = new Keyword.con1('FINAL', 13, "final");
  static final Keyword FINALLY = new Keyword.con1('FINALLY', 14, "finally");
  static final Keyword FOR = new Keyword.con1('FOR', 15, "for");
  static final Keyword IF = new Keyword.con1('IF', 16, "if");
  static final Keyword IN = new Keyword.con1('IN', 17, "in");
  static final Keyword IS = new Keyword.con1('IS', 18, "is");
  static final Keyword NEW = new Keyword.con1('NEW', 19, "new");
  static final Keyword NULL = new Keyword.con1('NULL', 20, "null");
  static final Keyword RETHROW = new Keyword.con1('RETHROW', 21, "rethrow");
  static final Keyword RETURN = new Keyword.con1('RETURN', 22, "return");
  static final Keyword SUPER = new Keyword.con1('SUPER', 23, "super");
  static final Keyword SWITCH = new Keyword.con1('SWITCH', 24, "switch");
  static final Keyword THIS = new Keyword.con1('THIS', 25, "this");
  static final Keyword THROW = new Keyword.con1('THROW', 26, "throw");
  static final Keyword TRUE = new Keyword.con1('TRUE', 27, "true");
  static final Keyword TRY = new Keyword.con1('TRY', 28, "try");
  static final Keyword VAR = new Keyword.con1('VAR', 29, "var");
  static final Keyword VOID = new Keyword.con1('VOID', 30, "void");
  static final Keyword WHILE = new Keyword.con1('WHILE', 31, "while");
  static final Keyword WITH = new Keyword.con1('WITH', 32, "with");
  static final Keyword ABSTRACT = new Keyword.con2('ABSTRACT', 33, "abstract", true);
  static final Keyword AS = new Keyword.con2('AS', 34, "as", true);
  static final Keyword DYNAMIC = new Keyword.con2('DYNAMIC', 35, "dynamic", true);
  static final Keyword EXPORT = new Keyword.con2('EXPORT', 36, "export", true);
  static final Keyword EXTERNAL = new Keyword.con2('EXTERNAL', 37, "external", true);
  static final Keyword FACTORY = new Keyword.con2('FACTORY', 38, "factory", true);
  static final Keyword GET = new Keyword.con2('GET', 39, "get", true);
  static final Keyword IMPLEMENTS = new Keyword.con2('IMPLEMENTS', 40, "implements", true);
  static final Keyword IMPORT = new Keyword.con2('IMPORT', 41, "import", true);
  static final Keyword LIBRARY = new Keyword.con2('LIBRARY', 42, "library", true);
  static final Keyword OPERATOR = new Keyword.con2('OPERATOR', 43, "operator", true);
  static final Keyword PART = new Keyword.con2('PART', 44, "part", true);
  static final Keyword SET = new Keyword.con2('SET', 45, "set", true);
  static final Keyword STATIC = new Keyword.con2('STATIC', 46, "static", true);
  static final Keyword TYPEDEF = new Keyword.con2('TYPEDEF', 47, "typedef", true);
  static final List<Keyword> values = [
      ASSERT,
      BREAK,
      CASE,
      CATCH,
      CLASS,
      CONST,
      CONTINUE,
      DEFAULT,
      DO,
      ELSE,
      ENUM,
      EXTENDS,
      FALSE,
      FINAL,
      FINALLY,
      FOR,
      IF,
      IN,
      IS,
      NEW,
      NULL,
      RETHROW,
      RETURN,
      SUPER,
      SWITCH,
      THIS,
      THROW,
      TRUE,
      TRY,
      VAR,
      VOID,
      WHILE,
      WITH,
      ABSTRACT,
      AS,
      DYNAMIC,
      EXPORT,
      EXTERNAL,
      FACTORY,
      GET,
      IMPLEMENTS,
      IMPORT,
      LIBRARY,
      OPERATOR,
      PART,
      SET,
      STATIC,
      TYPEDEF];

  /**
   * The lexeme for the keyword.
   */
  String syntax;

  /**
   * A flag indicating whether the keyword is a pseudo-keyword. Pseudo keywords can be used as
   * identifiers.
   */
  bool isPseudoKeyword = false;

  /**
   * A table mapping the lexemes of keywords to the corresponding keyword.
   */
  static Map<String, Keyword> keywords = createKeywordMap();

  /**
   * Create a table mapping the lexemes of keywords to the corresponding keyword.
   *
   * @return the table that was created
   */
  static Map<String, Keyword> createKeywordMap() {
    LinkedHashMap<String, Keyword> result = new LinkedHashMap<String, Keyword>();
    for (Keyword keyword in values) {
      result[keyword.syntax] = keyword;
    }
    return result;
  }

  /**
   * Initialize a newly created keyword to have the given syntax. The keyword is not a
   * pseudo-keyword.
   *
   * @param syntax the lexeme for the keyword
   */
  Keyword.con1(String name, int ordinal, String syntax) : this.con2(name, ordinal, syntax, false);

  /**
   * Initialize a newly created keyword to have the given syntax. The keyword is a pseudo-keyword if
   * the given flag is `true`.
   *
   * @param syntax the lexeme for the keyword
   * @param isPseudoKeyword `true` if this keyword is a pseudo-keyword
   */
  Keyword.con2(String name, int ordinal, String syntax, bool isPseudoKeyword) : super(name, ordinal) {
    this.syntax = syntax;
    this.isPseudoKeyword = isPseudoKeyword;
  }
}
/**
 * The abstract class `AbstractScanner` implements a scanner for Dart code. Subclasses are
 * required to implement the interface used to access the characters being scanned.
 *
 * The lexical structure of Dart is ambiguous without knowledge of the context in which a token is
 * being scanned. For example, without context we cannot determine whether source of the form "<<"
 * should be scanned as a single left-shift operator or as two left angle brackets. This scanner
 * does not have any context, so it always resolves such conflicts by scanning the longest possible
 * token.
 *
 * @coverage dart.engine.parser
 */
abstract class AbstractScanner {

  /**
   * The source being scanned.
   */
  Source source;

  /**
   * The error listener that will be informed of any errors that are found during the scan.
   */
  AnalysisErrorListener _errorListener;

  /**
   * The token pointing to the head of the linked list of tokens.
   */
  Token _tokens;

  /**
   * The last token that was scanned.
   */
  Token _tail;

  /**
   * The first token in the list of comment tokens found since the last non-comment token.
   */
  Token _firstComment;

  /**
   * The last token in the list of comment tokens found since the last non-comment token.
   */
  Token _lastComment;

  /**
   * The index of the first character of the current token.
   */
  int _tokenStart = 0;

  /**
   * A list containing the offsets of the first character of each line in the source code.
   */
  List<int> _lineStarts = new List<int>();

  /**
   * A list, treated something like a stack, of tokens representing the beginning of a matched pair.
   * It is used to pair the end tokens with the begin tokens.
   */
  List<BeginToken> _groupingStack = new List<BeginToken>();

  /**
   * A flag indicating whether any unmatched groups were found during the parse.
   */
  bool _hasUnmatchedGroups2 = false;

  /**
   * Initialize a newly created scanner.
   *
   * @param source the source being scanned
   * @param errorListener the error listener that will be informed of any errors that are found
   */
  AbstractScanner(Source source, AnalysisErrorListener errorListener) {
    this.source = source;
    this._errorListener = errorListener;
    _tokens = new Token(TokenType.EOF, -1);
    _tokens.setNext(_tokens);
    _tail = _tokens;
    _tokenStart = -1;
    _lineStarts.add(0);
  }

  /**
   * Return an array containing the offsets of the first character of each line in the source code.
   *
   * @return an array containing the offsets of the first character of each line in the source code
   */
  List<int> get lineStarts => _lineStarts;

  /**
   * Return the current offset relative to the beginning of the file. Return the initial offset if
   * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
   * the source code has been scanned.
   *
   * @return the current offset of the scanner in the source
   */
  int get offset;

  /**
   * Return `true` if any unmatched groups were found during the parse.
   *
   * @return `true` if any unmatched groups were found during the parse
   */
  bool hasUnmatchedGroups() => _hasUnmatchedGroups2;

  /**
   * Scan the source code to produce a list of tokens representing the source.
   *
   * @return the first token in the list of tokens that were produced
   */
  Token tokenize() {
    InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.AbstractScanner.tokenize");
    int tokenCounter = 0;
    try {
      int next = advance();
      while (next != -1) {
        tokenCounter++;
        next = bigSwitch(next);
      }
      appendEofToken();
      instrumentation.metric2("tokensCount", tokenCounter);
      return firstToken();
    } finally {
      instrumentation.log2(2);
    }
  }

  /**
   * Advance the current position and return the character at the new current position.
   *
   * @return the character at the new current position
   */
  int advance();

  /**
   * Return the substring of the source code between the start offset and the modified current
   * position. The current position is modified by adding the end delta.
   *
   * @param start the offset to the beginning of the string, relative to the start of the file
   * @param endDelta the number of character after the current location to be included in the
   *          string, or the number of characters before the current location to be excluded if the
   *          offset is negative
   * @return the specified substring of the source code
   */
  String getString(int start, int endDelta);

  /**
   * Return the character at the current position without changing the current position.
   *
   * @return the character at the current position
   */
  int peek();

  /**
   * Record the fact that we are at the beginning of a new line in the source.
   */
  void recordStartOfLine() {
    _lineStarts.add(offset);
  }
  void appendBeginToken(TokenType type) {
    BeginToken token;
    if (_firstComment == null) {
      token = new BeginToken(type, _tokenStart);
    } else {
      token = new BeginTokenWithComment(type, _tokenStart, _firstComment);
      _firstComment = null;
      _lastComment = null;
    }
    _tail = _tail.setNext(token);
    _groupingStack.add(token);
  }
  void appendCommentToken(TokenType type, String value) {
    if (_firstComment == null) {
      _firstComment = new StringToken(type, value, _tokenStart);
      _lastComment = _firstComment;
    } else {
      _lastComment = _lastComment.setNext(new StringToken(type, value, _tokenStart));
    }
  }
  void appendEndToken(TokenType type2, TokenType beginType) {
    Token token;
    if (_firstComment == null) {
      token = new Token(type2, _tokenStart);
    } else {
      token = new TokenWithComment(type2, _tokenStart, _firstComment);
      _firstComment = null;
      _lastComment = null;
    }
    _tail = _tail.setNext(token);
    int last = _groupingStack.length - 1;
    if (last >= 0) {
      BeginToken begin = _groupingStack[last];
      if (identical(begin.type, beginType)) {
        begin.endToken = token;
        _groupingStack.removeAt(last);
      }
    }
  }
  void appendEofToken() {
    Token eofToken;
    if (_firstComment == null) {
      eofToken = new Token(TokenType.EOF, offset + 1);
    } else {
      eofToken = new TokenWithComment(TokenType.EOF, offset + 1, _firstComment);
      _firstComment = null;
      _lastComment = null;
    }
    eofToken.setNext(eofToken);
    _tail = _tail.setNext(eofToken);
    if (!_groupingStack.isEmpty) {
      _hasUnmatchedGroups2 = true;
    }
  }
  void appendKeywordToken(Keyword keyword) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new KeywordToken(keyword, _tokenStart));
    } else {
      _tail = _tail.setNext(new KeywordTokenWithComment(keyword, _tokenStart, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }
  void appendStringToken(TokenType type, String value) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new StringToken(type, value, _tokenStart));
    } else {
      _tail = _tail.setNext(new StringTokenWithComment(type, value, _tokenStart, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }
  void appendStringToken2(TokenType type, String value, int offset) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new StringToken(type, value, _tokenStart + offset));
    } else {
      _tail = _tail.setNext(new StringTokenWithComment(type, value, _tokenStart + offset, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }
  void appendToken(TokenType type) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new Token(type, _tokenStart));
    } else {
      _tail = _tail.setNext(new TokenWithComment(type, _tokenStart, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }
  void appendToken2(TokenType type, int offset) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new Token(type, offset));
    } else {
      _tail = _tail.setNext(new TokenWithComment(type, offset, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }
  void beginToken() {
    _tokenStart = offset;
  }
  int bigSwitch(int next) {
    beginToken();
    if (next == 0xD) {
      next = advance();
      if (next == 0xA) {
        next = advance();
      }
      recordStartOfLine();
      return next;
    } else if (next == 0xA) {
      next = advance();
      recordStartOfLine();
      return next;
    } else if (next == 0x9 || next == 0x20) {
      return advance();
    }
    if (next == 0x72) {
      int peek2 = peek();
      if (peek2 == 0x22 || peek2 == 0x27) {
        int start = offset;
        return tokenizeString(advance(), start, true);
      }
    }
    if (0x61 <= next && next <= 0x7A) {
      return tokenizeKeywordOrIdentifier(next, true);
    }
    if ((0x41 <= next && next <= 0x5A) || next == 0x5F || next == 0x24) {
      return tokenizeIdentifier(next, offset, true);
    }
    if (next == 0x3C) {
      return tokenizeLessThan(next);
    }
    if (next == 0x3E) {
      return tokenizeGreaterThan(next);
    }
    if (next == 0x3D) {
      return tokenizeEquals(next);
    }
    if (next == 0x21) {
      return tokenizeExclamation(next);
    }
    if (next == 0x2B) {
      return tokenizePlus(next);
    }
    if (next == 0x2D) {
      return tokenizeMinus(next);
    }
    if (next == 0x2A) {
      return tokenizeMultiply(next);
    }
    if (next == 0x25) {
      return tokenizePercent(next);
    }
    if (next == 0x26) {
      return tokenizeAmpersand(next);
    }
    if (next == 0x7C) {
      return tokenizeBar(next);
    }
    if (next == 0x5E) {
      return tokenizeCaret(next);
    }
    if (next == 0x5B) {
      return tokenizeOpenSquareBracket(next);
    }
    if (next == 0x7E) {
      return tokenizeTilde(next);
    }
    if (next == 0x5C) {
      appendToken(TokenType.BACKSLASH);
      return advance();
    }
    if (next == 0x23) {
      return tokenizeTag(next);
    }
    if (next == 0x28) {
      appendBeginToken(TokenType.OPEN_PAREN);
      return advance();
    }
    if (next == 0x29) {
      appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
      return advance();
    }
    if (next == 0x2C) {
      appendToken(TokenType.COMMA);
      return advance();
    }
    if (next == 0x3A) {
      appendToken(TokenType.COLON);
      return advance();
    }
    if (next == 0x3B) {
      appendToken(TokenType.SEMICOLON);
      return advance();
    }
    if (next == 0x3F) {
      appendToken(TokenType.QUESTION);
      return advance();
    }
    if (next == 0x5D) {
      appendEndToken(TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
      return advance();
    }
    if (next == 0x60) {
      appendToken(TokenType.BACKPING);
      return advance();
    }
    if (next == 0x7B) {
      appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
      return advance();
    }
    if (next == 0x7D) {
      appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
      return advance();
    }
    if (next == 0x2F) {
      return tokenizeSlashOrComment(next);
    }
    if (next == 0x40) {
      appendToken(TokenType.AT);
      return advance();
    }
    if (next == 0x22 || next == 0x27) {
      return tokenizeString(next, offset, false);
    }
    if (next == 0x2E) {
      return tokenizeDotOrNumber(next);
    }
    if (next == 0x30) {
      return tokenizeHexOrNumber(next);
    }
    if (0x31 <= next && next <= 0x39) {
      return tokenizeNumber(next);
    }
    if (next == -1) {
      return -1;
    }
    reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
    return advance();
  }

  /**
   * Return the beginning token corresponding to a closing brace that was found while scanning
   * inside a string interpolation expression. Tokens that cannot be matched with the closing brace
   * will be dropped from the stack.
   *
   * @return the token to be paired with the closing brace
   */
  BeginToken findTokenMatchingClosingBraceInInterpolationExpression() {
    int last = _groupingStack.length - 1;
    while (last >= 0) {
      BeginToken begin = _groupingStack[last];
      if (identical(begin.type, TokenType.OPEN_CURLY_BRACKET) || identical(begin.type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
        return begin;
      }
      _hasUnmatchedGroups2 = true;
      _groupingStack.removeAt(last);
      last--;
    }
    return null;
  }
  Token firstToken() => _tokens.next;

  /**
   * Report an error at the current offset.
   *
   * @param errorCode the error code indicating the nature of the error
   * @param arguments any arguments needed to complete the error message
   */
  void reportError(ScannerErrorCode errorCode, List<Object> arguments) {
    _errorListener.onError(new AnalysisError.con2(source, offset, 1, errorCode, arguments));
  }
  int select(int choice, TokenType yesType, TokenType noType) {
    int next = advance();
    if (next == choice) {
      appendToken(yesType);
      return advance();
    } else {
      appendToken(noType);
      return next;
    }
  }
  int select2(int choice, TokenType yesType, TokenType noType, int offset) {
    int next = advance();
    if (next == choice) {
      appendToken2(yesType, offset);
      return advance();
    } else {
      appendToken2(noType, offset);
      return next;
    }
  }
  int tokenizeAmpersand(int next) {
    next = advance();
    if (next == 0x26) {
      appendToken(TokenType.AMPERSAND_AMPERSAND);
      return advance();
    } else if (next == 0x3D) {
      appendToken(TokenType.AMPERSAND_EQ);
      return advance();
    } else {
      appendToken(TokenType.AMPERSAND);
      return next;
    }
  }
  int tokenizeBar(int next) {
    next = advance();
    if (next == 0x7C) {
      appendToken(TokenType.BAR_BAR);
      return advance();
    } else if (next == 0x3D) {
      appendToken(TokenType.BAR_EQ);
      return advance();
    } else {
      appendToken(TokenType.BAR);
      return next;
    }
  }
  int tokenizeCaret(int next) => select(0x3D, TokenType.CARET_EQ, TokenType.CARET);
  int tokenizeDotOrNumber(int next) {
    int start = offset;
    next = advance();
    if ((0x30 <= next && next <= 0x39)) {
      return tokenizeFractionPart(next, start);
    } else if (0x2E == next) {
      return select(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
    } else {
      appendToken(TokenType.PERIOD);
      return next;
    }
  }
  int tokenizeEquals(int next) {
    next = advance();
    if (next == 0x3D) {
      appendToken(TokenType.EQ_EQ);
      return advance();
    } else if (next == 0x3E) {
      appendToken(TokenType.FUNCTION);
      return advance();
    }
    appendToken(TokenType.EQ);
    return next;
  }
  int tokenizeExclamation(int next) {
    next = advance();
    if (next == 0x3D) {
      appendToken(TokenType.BANG_EQ);
      return advance();
    }
    appendToken(TokenType.BANG);
    return next;
  }
  int tokenizeExponent(int next) {
    if (next == 0x2B || next == 0x2D) {
      next = advance();
    }
    bool hasDigits = false;
    while (true) {
      if (0x30 <= next && next <= 0x39) {
        hasDigits = true;
      } else {
        if (!hasDigits) {
          reportError(ScannerErrorCode.MISSING_DIGIT, []);
        }
        return next;
      }
      next = advance();
    }
  }
  int tokenizeFractionPart(int next, int start) {
    bool done = false;
    bool hasDigit = false;
    LOOP: while (!done) {
      if (0x30 <= next && next <= 0x39) {
        hasDigit = true;
      } else if (0x65 == next || 0x45 == next) {
        hasDigit = true;
        next = tokenizeExponent(advance());
        done = true;
        continue LOOP;
      } else {
        done = true;
        continue LOOP;
      }
      next = advance();
    }
    if (!hasDigit) {
      appendStringToken(TokenType.INT, getString(start, -2));
      if (0x2E == next) {
        return select2(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
      }
      appendToken2(TokenType.PERIOD, offset - 1);
      return bigSwitch(next);
    }
    appendStringToken(TokenType.DOUBLE, getString(start, next < 0 ? 0 : -1));
    return next;
  }
  int tokenizeGreaterThan(int next) {
    next = advance();
    if (0x3D == next) {
      appendToken(TokenType.GT_EQ);
      return advance();
    } else if (0x3E == next) {
      next = advance();
      if (0x3D == next) {
        appendToken(TokenType.GT_GT_EQ);
        return advance();
      } else {
        appendToken(TokenType.GT_GT);
        return next;
      }
    } else {
      appendToken(TokenType.GT);
      return next;
    }
  }
  int tokenizeHex(int next) {
    int start = offset - 1;
    bool hasDigits = false;
    while (true) {
      next = advance();
      if ((0x30 <= next && next <= 0x39) || (0x41 <= next && next <= 0x46) || (0x61 <= next && next <= 0x66)) {
        hasDigits = true;
      } else {
        if (!hasDigits) {
          reportError(ScannerErrorCode.MISSING_HEX_DIGIT, []);
        }
        appendStringToken(TokenType.HEXADECIMAL, getString(start, next < 0 ? 0 : -1));
        return next;
      }
    }
  }
  int tokenizeHexOrNumber(int next) {
    int x = peek();
    if (x == 0x78 || x == 0x58) {
      advance();
      return tokenizeHex(x);
    }
    return tokenizeNumber(next);
  }
  int tokenizeIdentifier(int next, int start, bool allowDollar) {
    while ((0x61 <= next && next <= 0x7A) || (0x41 <= next && next <= 0x5A) || (0x30 <= next && next <= 0x39) || next == 0x5F || (next == 0x24 && allowDollar)) {
      next = advance();
    }
    appendStringToken(TokenType.IDENTIFIER, getString(start, next < 0 ? 0 : -1));
    return next;
  }
  int tokenizeInterpolatedExpression(int next, int start) {
    appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
    next = advance();
    while (next != -1) {
      if (next == 0x7D) {
        BeginToken begin = findTokenMatchingClosingBraceInInterpolationExpression();
        if (begin == null) {
          beginToken();
          appendToken(TokenType.CLOSE_CURLY_BRACKET);
          next = advance();
          beginToken();
          return next;
        } else if (identical(begin.type, TokenType.OPEN_CURLY_BRACKET)) {
          beginToken();
          appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
          next = advance();
          beginToken();
        } else if (identical(begin.type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
          beginToken();
          appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.STRING_INTERPOLATION_EXPRESSION);
          next = advance();
          beginToken();
          return next;
        }
      } else {
        next = bigSwitch(next);
      }
    }
    if (next == -1) {
      return next;
    }
    next = advance();
    beginToken();
    return next;
  }
  int tokenizeInterpolatedIdentifier(int next, int start) {
    appendStringToken2(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 0);
    if (((0x41 <= next && next <= 0x5A) || (0x61 <= next && next <= 0x7A) || next == 0x5F)) {
      beginToken();
      next = tokenizeKeywordOrIdentifier(next, false);
    }
    beginToken();
    return next;
  }
  int tokenizeKeywordOrIdentifier(int next2, bool allowDollar) {
    KeywordState state = KeywordState.KEYWORD_STATE;
    int start = offset;
    while (state != null && 0x61 <= next2 && next2 <= 0x7A) {
      state = state.next(next2 as int);
      next2 = advance();
    }
    if (state == null || state.keyword() == null) {
      return tokenizeIdentifier(next2, start, allowDollar);
    }
    if ((0x41 <= next2 && next2 <= 0x5A) || (0x30 <= next2 && next2 <= 0x39) || next2 == 0x5F || next2 == 0x24) {
      return tokenizeIdentifier(next2, start, allowDollar);
    } else if (next2 < 128) {
      appendKeywordToken(state.keyword());
      return next2;
    } else {
      return tokenizeIdentifier(next2, start, allowDollar);
    }
  }
  int tokenizeLessThan(int next) {
    next = advance();
    if (0x3D == next) {
      appendToken(TokenType.LT_EQ);
      return advance();
    } else if (0x3C == next) {
      return select(0x3D, TokenType.LT_LT_EQ, TokenType.LT_LT);
    } else {
      appendToken(TokenType.LT);
      return next;
    }
  }
  int tokenizeMinus(int next) {
    next = advance();
    if (next == 0x2D) {
      appendToken(TokenType.MINUS_MINUS);
      return advance();
    } else if (next == 0x3D) {
      appendToken(TokenType.MINUS_EQ);
      return advance();
    } else {
      appendToken(TokenType.MINUS);
      return next;
    }
  }
  int tokenizeMultiLineComment(int next) {
    int nesting = 1;
    next = advance();
    while (true) {
      if (-1 == next) {
        reportError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, []);
        appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
        return next;
      } else if (0x2A == next) {
        next = advance();
        if (0x2F == next) {
          --nesting;
          if (0 == nesting) {
            appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
            return advance();
          } else {
            next = advance();
          }
        }
      } else if (0x2F == next) {
        next = advance();
        if (0x2A == next) {
          next = advance();
          ++nesting;
        }
      } else if (next == 0xD) {
        next = advance();
        if (next == 0xA) {
          next = advance();
        }
        recordStartOfLine();
      } else if (next == 0xA) {
        recordStartOfLine();
        next = advance();
      } else {
        next = advance();
      }
    }
  }
  int tokenizeMultiLineRawString(int quoteChar, int start) {
    int next = advance();
    outer: while (next != -1) {
      while (next != quoteChar) {
        next = advance();
        if (next == -1) {
          break outer;
        }
      }
      next = advance();
      if (next == quoteChar) {
        next = advance();
        if (next == quoteChar) {
          appendStringToken(TokenType.STRING, getString(start, 0));
          return advance();
        }
      }
    }
    reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
    appendStringToken(TokenType.STRING, getString(start, 0));
    return advance();
  }
  int tokenizeMultiLineString(int quoteChar, int start, bool raw) {
    if (raw) {
      return tokenizeMultiLineRawString(quoteChar, start);
    }
    int next = advance();
    while (next != -1) {
      if (next == 0x24) {
        appendStringToken(TokenType.STRING, getString(start, -1));
        beginToken();
        next = tokenizeStringInterpolation(start);
        start = offset;
        continue;
      }
      if (next == quoteChar) {
        next = advance();
        if (next == quoteChar) {
          next = advance();
          if (next == quoteChar) {
            appendStringToken(TokenType.STRING, getString(start, 0));
            return advance();
          }
        }
        continue;
      }
      if (next == 0x5C) {
        next = advance();
        if (next == -1) {
          break;
        }
        if (next == 0xD || next == 0xA) {
          _errorListener.onError(new AnalysisError.con2(source, offset - 1, 1, ScannerErrorCode.CHARACTER_EXPECTED_AFTER_SLASH, []));
        }
      }
      next = advance();
    }
    reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
    appendStringToken(TokenType.STRING, getString(start, 0));
    return advance();
  }
  int tokenizeMultiply(int next) => select(0x3D, TokenType.STAR_EQ, TokenType.STAR);
  int tokenizeNumber(int next) {
    int start = offset;
    while (true) {
      next = advance();
      if (0x30 <= next && next <= 0x39) {
        continue;
      } else if (next == 0x2E) {
        return tokenizeFractionPart(advance(), start);
      } else if (next == 0x65 || next == 0x45) {
        return tokenizeFractionPart(next, start);
      } else {
        appendStringToken(TokenType.INT, getString(start, next < 0 ? 0 : -1));
        return next;
      }
    }
  }
  int tokenizeOpenSquareBracket(int next) {
    next = advance();
    if (next == 0x5D) {
      return select(0x3D, TokenType.INDEX_EQ, TokenType.INDEX);
    } else {
      appendBeginToken(TokenType.OPEN_SQUARE_BRACKET);
      return next;
    }
  }
  int tokenizePercent(int next) => select(0x3D, TokenType.PERCENT_EQ, TokenType.PERCENT);
  int tokenizePlus(int next) {
    next = advance();
    if (0x2B == next) {
      appendToken(TokenType.PLUS_PLUS);
      return advance();
    } else if (0x3D == next) {
      appendToken(TokenType.PLUS_EQ);
      return advance();
    } else {
      appendToken(TokenType.PLUS);
      return next;
    }
  }
  int tokenizeSingleLineComment(int next) {
    while (true) {
      next = advance();
      if (-1 == next) {
        appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, 0));
        return next;
      } else if (0xA == next || 0xD == next) {
        appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, -1));
        return next;
      }
    }
  }
  int tokenizeSingleLineRawString(int next, int quoteChar, int start) {
    next = advance();
    while (next != -1) {
      if (next == quoteChar) {
        appendStringToken(TokenType.STRING, getString(start, 0));
        return advance();
      } else if (next == 0xD || next == 0xA) {
        reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
        appendStringToken(TokenType.STRING, getString(start, 0));
        return advance();
      }
      next = advance();
    }
    reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
    appendStringToken(TokenType.STRING, getString(start, 0));
    return advance();
  }
  int tokenizeSingleLineString(int next, int quoteChar, int start) {
    while (next != quoteChar) {
      if (next == 0x5C) {
        next = advance();
      } else if (next == 0x24) {
        appendStringToken(TokenType.STRING, getString(start, -1));
        beginToken();
        next = tokenizeStringInterpolation(start);
        start = offset;
        continue;
      }
      if (next <= 0xD && (next == 0xA || next == 0xD || next == -1)) {
        reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
        appendStringToken(TokenType.STRING, getString(start, 0));
        return advance();
      }
      next = advance();
    }
    appendStringToken(TokenType.STRING, getString(start, 0));
    return advance();
  }
  int tokenizeSlashOrComment(int next) {
    next = advance();
    if (0x2A == next) {
      return tokenizeMultiLineComment(next);
    } else if (0x2F == next) {
      return tokenizeSingleLineComment(next);
    } else if (0x3D == next) {
      appendToken(TokenType.SLASH_EQ);
      return advance();
    } else {
      appendToken(TokenType.SLASH);
      return next;
    }
  }
  int tokenizeString(int next, int start, bool raw) {
    int quoteChar = next;
    next = advance();
    if (quoteChar == next) {
      next = advance();
      if (quoteChar == next) {
        return tokenizeMultiLineString(quoteChar, start, raw);
      } else {
        appendStringToken(TokenType.STRING, getString(start, -1));
        return next;
      }
    }
    if (raw) {
      return tokenizeSingleLineRawString(next, quoteChar, start);
    } else {
      return tokenizeSingleLineString(next, quoteChar, start);
    }
  }
  int tokenizeStringInterpolation(int start) {
    beginToken();
    int next = advance();
    if (next == 0x7B) {
      return tokenizeInterpolatedExpression(next, start);
    } else {
      return tokenizeInterpolatedIdentifier(next, start);
    }
  }
  int tokenizeTag(int next) {
    if (offset == 0) {
      if (peek() == 0x21) {
        do {
          next = advance();
        } while (next != 0xA && next != 0xD && next > 0);
        appendStringToken(TokenType.SCRIPT_TAG, getString(_tokenStart, 0));
        return next;
      }
    }
    appendToken(TokenType.HASH);
    return advance();
  }
  int tokenizeTilde(int next) {
    next = advance();
    if (next == 0x2F) {
      return select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
    } else {
      appendToken(TokenType.TILDE);
      return next;
    }
  }
}
/**
 * Instances of the class `StringToken` represent a token whose value is independent of it's
 * type.
 *
 * @coverage dart.engine.parser
 */
class StringToken extends Token {

  /**
   * The lexeme represented by this token.
   */
  String _value2;

  /**
   * Initialize a newly created token to represent a token of the given type with the given value.
   *
   * @param type the type of the token
   * @param value the lexeme represented by this token
   * @param offset the offset from the beginning of the file to the first character in the token
   */
  StringToken(TokenType type, String value, int offset) : super(type, offset) {
    this._value2 = StringUtilities.intern(value);
  }
  String get lexeme => _value2;
  String value() => _value2;
}
/**
 * Instances of the class `CharBufferScanner` implement a scanner that reads from a character
 * buffer. The scanning logic is in the superclass.
 *
 * @coverage dart.engine.parser
 */
class CharBufferScanner extends AbstractScanner {

  /**
   * The buffer from which characters will be read.
   */
  CharBuffer _buffer;

  /**
   * The number of characters in the buffer.
   */
  int _bufferLength = 0;

  /**
   * The index of the last character that was read.
   */
  int _charOffset = 0;

  /**
   * Initialize a newly created scanner to scan the characters in the given character buffer.
   *
   * @param source the source being scanned
   * @param buffer the buffer from which characters will be read
   * @param errorListener the error listener that will be informed of any errors that are found
   */
  CharBufferScanner(Source source, CharBuffer buffer, AnalysisErrorListener errorListener) : super(source, errorListener) {
    this._buffer = buffer;
    this._bufferLength = buffer.length();
    this._charOffset = -1;
  }
  int get offset => _charOffset;
  int advance() {
    if (_charOffset + 1 >= _bufferLength) {
      return -1;
    }
    return _buffer.charAt(++_charOffset);
  }
  String getString(int start, int endDelta) => ((_buffer as CharSequence)).subSequence(start, _charOffset + 1 + endDelta).toString();
  int peek() {
    if (_charOffset + 1 >= _buffer.length()) {
      return -1;
    }
    return _buffer.charAt(_charOffset + 1);
  }
}
/**
 * Instances of the class `TokenWithComment` represent a normal token that is preceded by
 * comments.
 *
 * @coverage dart.engine.parser
 */
class TokenWithComment extends Token {

  /**
   * The first comment in the list of comments that precede this token.
   */
  Token _precedingComment;

  /**
   * Initialize a newly created token to have the given type and offset and to be preceded by the
   * comments reachable from the given comment.
   *
   * @param type the type of the token
   * @param offset the offset from the beginning of the file to the first character in the token
   * @param precedingComment the first comment in the list of comments that precede this token
   */
  TokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
    this._precedingComment = precedingComment;
  }
  Token get precedingComments => _precedingComment;
}
/**
 * Instances of the class `Token` represent a token that was scanned from the input. Each
 * token knows which token follows it, acting as the head of a linked list of tokens.
 *
 * @coverage dart.engine.parser
 */
class Token {

  /**
   * The type of the token.
   */
  TokenType type;

  /**
   * The offset from the beginning of the file to the first character in the token.
   */
  int offset = 0;

  /**
   * The previous token in the token stream.
   */
  Token previous;

  /**
   * The next token in the token stream.
   */
  Token next;

  /**
   * Initialize a newly created token to have the given type and offset.
   *
   * @param type the type of the token
   * @param offset the offset from the beginning of the file to the first character in the token
   */
  Token(TokenType type, int offset) {
    this.type = type;
    this.offset = offset;
  }

  /**
   * Return the offset from the beginning of the file to the character after last character of the
   * token.
   *
   * @return the offset from the beginning of the file to the first character after last character
   *         of the token
   */
  int get end => offset + length;

  /**
   * Return the number of characters in the node's source range.
   *
   * @return the number of characters in the node's source range
   */
  int get length => lexeme.length;

  /**
   * Return the lexeme that represents this token.
   *
   * @return the lexeme that represents this token
   */
  String get lexeme => type.lexeme;

  /**
   * Return the first comment in the list of comments that precede this token, or `null` if
   * there are no comments preceding this token. Additional comments can be reached by following the
   * token stream using [getNext] until `null` is returned.
   *
   * @return the first comment in the list of comments that precede this token
   */
  Token get precedingComments => null;

  /**
   * Return `true` if this token represents an operator.
   *
   * @return `true` if this token represents an operator
   */
  bool get isOperator => type.isOperator;

  /**
   * Return `true` if this token is a synthetic token. A synthetic token is a token that was
   * introduced by the parser in order to recover from an error in the code. Synthetic tokens always
   * have a length of zero (`0`).
   *
   * @return `true` if this token is a synthetic token
   */
  bool get isSynthetic => length == 0;

  /**
   * Return `true` if this token represents an operator that can be defined by users.
   *
   * @return `true` if this token represents an operator that can be defined by users
   */
  bool get isUserDefinableOperator => type.isUserDefinableOperator;

  /**
   * Set the next token in the token stream to the given token. This has the side-effect of setting
   * this token to be the previous token for the given token.
   *
   * @param token the next token in the token stream
   * @return the token that was passed in
   */
  Token setNext(Token token) {
    next = token;
    token.previous = this;
    return token;
  }

  /**
   * Set the next token in the token stream to the given token without changing which token is the
   * previous token for the given token.
   *
   * @param token the next token in the token stream
   * @return the token that was passed in
   */
  Token setNextWithoutSettingPrevious(Token token) {
    next = token;
    return token;
  }
  String toString() => lexeme;

  /**
   * Return the value of this token. For keyword tokens, this is the keyword associated with the
   * token, for other tokens it is the lexeme associated with the token.
   *
   * @return the value of this token
   */
  Object value() => type.lexeme;
}
/**
 * Instances of the class `StringScanner` implement a scanner that reads from a string. The
 * scanning logic is in the superclass.
 *
 * @coverage dart.engine.parser
 */
class StringScanner extends AbstractScanner {

  /**
   * The offset from the beginning of the file to the beginning of the source being scanned.
   */
  int _offsetDelta = 0;

  /**
   * The string from which characters will be read.
   */
  String _string;

  /**
   * The number of characters in the string.
   */
  int _stringLength = 0;

  /**
   * The index, relative to the string, of the last character that was read.
   */
  int _charOffset = 0;

  /**
   * Initialize a newly created scanner to scan the characters in the given string.
   *
   * @param source the source being scanned
   * @param string the string from which characters will be read
   * @param errorListener the error listener that will be informed of any errors that are found
   */
  StringScanner(Source source, String string, AnalysisErrorListener errorListener) : super(source, errorListener) {
    this._offsetDelta = 0;
    this._string = string;
    this._stringLength = string.length;
    this._charOffset = -1;
  }
  int get offset => _offsetDelta + _charOffset;

  /**
   * Record that the source begins on the given line and column at the given offset. The line starts
   * for lines before the given line will not be correct.
   *
   * This method must be invoked at most one time and must be invoked before scanning begins. The
   * values provided must be sensible. The results are undefined if these conditions are violated.
   *
   * @param line the one-based index of the line containing the first character of the source
   * @param column the one-based index of the column in which the first character of the source
   *          occurs
   * @param offset the zero-based offset from the beginning of the larger context to the first
   *          character of the source
   */
  void setSourceStart(int line, int column, int offset) {
    if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
      return;
    }
    _offsetDelta = 1;
    for (int i = 2; i < line; i++) {
      recordStartOfLine();
    }
    _offsetDelta = offset - column + 1;
    recordStartOfLine();
    _offsetDelta = offset;
  }
  int advance() {
    if (_charOffset + 1 >= _stringLength) {
      return -1;
    }
    return _string.codeUnitAt(++_charOffset);
  }
  String getString(int start, int endDelta) => _string.substring(start - _offsetDelta, _charOffset + 1 + endDelta);
  int peek() {
    if (_charOffset + 1 >= _string.length) {
      return -1;
    }
    return _string.codeUnitAt(_charOffset + 1);
  }
}
/**
 * Instances of the class `BeginTokenWithComment` represent a begin token that is preceded by
 * comments.
 *
 * @coverage dart.engine.parser
 */
class BeginTokenWithComment extends BeginToken {

  /**
   * The first comment in the list of comments that precede this token.
   */
  Token _precedingComment;

  /**
   * Initialize a newly created token to have the given type and offset and to be preceded by the
   * comments reachable from the given comment.
   *
   * @param type the type of the token
   * @param offset the offset from the beginning of the file to the first character in the token
   * @param precedingComment the first comment in the list of comments that precede this token
   */
  BeginTokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
    this._precedingComment = precedingComment;
  }
  Token get precedingComments => _precedingComment;
}
/**
 * Instances of the class `KeywordToken` represent a keyword in the language.
 *
 * @coverage dart.engine.parser
 */
class KeywordToken extends Token {

  /**
   * The keyword being represented by this token.
   */
  Keyword keyword;

  /**
   * Initialize a newly created token to represent the given keyword.
   *
   * @param keyword the keyword being represented by this token
   * @param offset the offset from the beginning of the file to the first character in the token
   */
  KeywordToken(Keyword keyword, int offset) : super(TokenType.KEYWORD, offset) {
    this.keyword = keyword;
  }
  String get lexeme => keyword.syntax;
  Keyword value() => keyword;
}
/**
 * Instances of the class `BeginToken` represent the opening half of a grouping pair of
 * tokens. This is used for curly brackets ('{'), parentheses ('('), and square brackets ('[').
 *
 * @coverage dart.engine.parser
 */
class BeginToken extends Token {

  /**
   * The token that corresponds to this token.
   */
  Token endToken;

  /**
   * Initialize a newly created token representing the opening half of a grouping pair of tokens.
   *
   * @param type the type of the token
   * @param offset the offset from the beginning of the file to the first character in the token
   */
  BeginToken(TokenType type, int offset) : super(type, offset) {
    assert((identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, TokenType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)));
  }
}
/**
 * The enumeration `TokenClass` represents classes (or groups) of tokens with a similar use.
 *
 * @coverage dart.engine.parser
 */
class TokenClass extends Enum<TokenClass> {

  /**
   * A value used to indicate that the token type is not part of any specific class of token.
   */
  static final TokenClass NO_CLASS = new TokenClass.con1('NO_CLASS', 0);

  /**
   * A value used to indicate that the token type is an additive operator.
   */
  static final TokenClass ADDITIVE_OPERATOR = new TokenClass.con2('ADDITIVE_OPERATOR', 1, 12);

  /**
   * A value used to indicate that the token type is an assignment operator.
   */
  static final TokenClass ASSIGNMENT_OPERATOR = new TokenClass.con2('ASSIGNMENT_OPERATOR', 2, 1);

  /**
   * A value used to indicate that the token type is a bitwise-and operator.
   */
  static final TokenClass BITWISE_AND_OPERATOR = new TokenClass.con2('BITWISE_AND_OPERATOR', 3, 8);

  /**
   * A value used to indicate that the token type is a bitwise-or operator.
   */
  static final TokenClass BITWISE_OR_OPERATOR = new TokenClass.con2('BITWISE_OR_OPERATOR', 4, 6);

  /**
   * A value used to indicate that the token type is a bitwise-xor operator.
   */
  static final TokenClass BITWISE_XOR_OPERATOR = new TokenClass.con2('BITWISE_XOR_OPERATOR', 5, 7);

  /**
   * A value used to indicate that the token type is a cascade operator.
   */
  static final TokenClass CASCADE_OPERATOR = new TokenClass.con2('CASCADE_OPERATOR', 6, 2);

  /**
   * A value used to indicate that the token type is a conditional operator.
   */
  static final TokenClass CONDITIONAL_OPERATOR = new TokenClass.con2('CONDITIONAL_OPERATOR', 7, 3);

  /**
   * A value used to indicate that the token type is an equality operator.
   */
  static final TokenClass EQUALITY_OPERATOR = new TokenClass.con2('EQUALITY_OPERATOR', 8, 9);

  /**
   * A value used to indicate that the token type is a logical-and operator.
   */
  static final TokenClass LOGICAL_AND_OPERATOR = new TokenClass.con2('LOGICAL_AND_OPERATOR', 9, 5);

  /**
   * A value used to indicate that the token type is a logical-or operator.
   */
  static final TokenClass LOGICAL_OR_OPERATOR = new TokenClass.con2('LOGICAL_OR_OPERATOR', 10, 4);

  /**
   * A value used to indicate that the token type is a multiplicative operator.
   */
  static final TokenClass MULTIPLICATIVE_OPERATOR = new TokenClass.con2('MULTIPLICATIVE_OPERATOR', 11, 13);

  /**
   * A value used to indicate that the token type is a relational operator.
   */
  static final TokenClass RELATIONAL_OPERATOR = new TokenClass.con2('RELATIONAL_OPERATOR', 12, 10);

  /**
   * A value used to indicate that the token type is a shift operator.
   */
  static final TokenClass SHIFT_OPERATOR = new TokenClass.con2('SHIFT_OPERATOR', 13, 11);

  /**
   * A value used to indicate that the token type is a unary operator.
   */
  static final TokenClass UNARY_POSTFIX_OPERATOR = new TokenClass.con2('UNARY_POSTFIX_OPERATOR', 14, 15);

  /**
   * A value used to indicate that the token type is a unary operator.
   */
  static final TokenClass UNARY_PREFIX_OPERATOR = new TokenClass.con2('UNARY_PREFIX_OPERATOR', 15, 14);
  static final List<TokenClass> values = [
      NO_CLASS,
      ADDITIVE_OPERATOR,
      ASSIGNMENT_OPERATOR,
      BITWISE_AND_OPERATOR,
      BITWISE_OR_OPERATOR,
      BITWISE_XOR_OPERATOR,
      CASCADE_OPERATOR,
      CONDITIONAL_OPERATOR,
      EQUALITY_OPERATOR,
      LOGICAL_AND_OPERATOR,
      LOGICAL_OR_OPERATOR,
      MULTIPLICATIVE_OPERATOR,
      RELATIONAL_OPERATOR,
      SHIFT_OPERATOR,
      UNARY_POSTFIX_OPERATOR,
      UNARY_PREFIX_OPERATOR];

  /**
   * The precedence of tokens of this class, or `0` if the such tokens do not represent an
   * operator.
   */
  int precedence = 0;
  TokenClass.con1(String name, int ordinal) : this.con2(name, ordinal, 0);
  TokenClass.con2(String name, int ordinal, int precedence) : super(name, ordinal) {
    this.precedence = precedence;
  }
}
/**
 * Instances of the class `KeywordTokenWithComment` implement a keyword token that is preceded
 * by comments.
 *
 * @coverage dart.engine.parser
 */
class KeywordTokenWithComment extends KeywordToken {

  /**
   * The first comment in the list of comments that precede this token.
   */
  Token _precedingComment;

  /**
   * Initialize a newly created token to to represent the given keyword and to be preceded by the
   * comments reachable from the given comment.
   *
   * @param keyword the keyword being represented by this token
   * @param offset the offset from the beginning of the file to the first character in the token
   * @param precedingComment the first comment in the list of comments that precede this token
   */
  KeywordTokenWithComment(Keyword keyword, int offset, Token precedingComment) : super(keyword, offset) {
    this._precedingComment = precedingComment;
  }
  Token get precedingComments => _precedingComment;
}
/**
 * The enumeration `TokenType` defines the types of tokens that can be returned by the
 * scanner.
 *
 * @coverage dart.engine.parser
 */
class TokenType extends Enum<TokenType> {

  /**
   * The type of the token that marks the end of the input.
   */
  static final TokenType EOF = new TokenType_EOF('EOF', 0, null, "");
  static final TokenType DOUBLE = new TokenType.con1('DOUBLE', 1);
  static final TokenType HEXADECIMAL = new TokenType.con1('HEXADECIMAL', 2);
  static final TokenType IDENTIFIER = new TokenType.con1('IDENTIFIER', 3);
  static final TokenType INT = new TokenType.con1('INT', 4);
  static final TokenType KEYWORD = new TokenType.con1('KEYWORD', 5);
  static final TokenType MULTI_LINE_COMMENT = new TokenType.con1('MULTI_LINE_COMMENT', 6);
  static final TokenType SCRIPT_TAG = new TokenType.con1('SCRIPT_TAG', 7);
  static final TokenType SINGLE_LINE_COMMENT = new TokenType.con1('SINGLE_LINE_COMMENT', 8);
  static final TokenType STRING = new TokenType.con1('STRING', 9);
  static final TokenType AMPERSAND = new TokenType.con2('AMPERSAND', 10, TokenClass.BITWISE_AND_OPERATOR, "&");
  static final TokenType AMPERSAND_AMPERSAND = new TokenType.con2('AMPERSAND_AMPERSAND', 11, TokenClass.LOGICAL_AND_OPERATOR, "&&");
  static final TokenType AMPERSAND_EQ = new TokenType.con2('AMPERSAND_EQ', 12, TokenClass.ASSIGNMENT_OPERATOR, "&=");
  static final TokenType AT = new TokenType.con2('AT', 13, null, "@");
  static final TokenType BANG = new TokenType.con2('BANG', 14, TokenClass.UNARY_PREFIX_OPERATOR, "!");
  static final TokenType BANG_EQ = new TokenType.con2('BANG_EQ', 15, TokenClass.EQUALITY_OPERATOR, "!=");
  static final TokenType BAR = new TokenType.con2('BAR', 16, TokenClass.BITWISE_OR_OPERATOR, "|");
  static final TokenType BAR_BAR = new TokenType.con2('BAR_BAR', 17, TokenClass.LOGICAL_OR_OPERATOR, "||");
  static final TokenType BAR_EQ = new TokenType.con2('BAR_EQ', 18, TokenClass.ASSIGNMENT_OPERATOR, "|=");
  static final TokenType COLON = new TokenType.con2('COLON', 19, null, ":");
  static final TokenType COMMA = new TokenType.con2('COMMA', 20, null, ",");
  static final TokenType CARET = new TokenType.con2('CARET', 21, TokenClass.BITWISE_XOR_OPERATOR, "^");
  static final TokenType CARET_EQ = new TokenType.con2('CARET_EQ', 22, TokenClass.ASSIGNMENT_OPERATOR, "^=");
  static final TokenType CLOSE_CURLY_BRACKET = new TokenType.con2('CLOSE_CURLY_BRACKET', 23, null, "}");
  static final TokenType CLOSE_PAREN = new TokenType.con2('CLOSE_PAREN', 24, null, ")");
  static final TokenType CLOSE_SQUARE_BRACKET = new TokenType.con2('CLOSE_SQUARE_BRACKET', 25, null, "]");
  static final TokenType EQ = new TokenType.con2('EQ', 26, TokenClass.ASSIGNMENT_OPERATOR, "=");
  static final TokenType EQ_EQ = new TokenType.con2('EQ_EQ', 27, TokenClass.EQUALITY_OPERATOR, "==");
  static final TokenType FUNCTION = new TokenType.con2('FUNCTION', 28, null, "=>");
  static final TokenType GT = new TokenType.con2('GT', 29, TokenClass.RELATIONAL_OPERATOR, ">");
  static final TokenType GT_EQ = new TokenType.con2('GT_EQ', 30, TokenClass.RELATIONAL_OPERATOR, ">=");
  static final TokenType GT_GT = new TokenType.con2('GT_GT', 31, TokenClass.SHIFT_OPERATOR, ">>");
  static final TokenType GT_GT_EQ = new TokenType.con2('GT_GT_EQ', 32, TokenClass.ASSIGNMENT_OPERATOR, ">>=");
  static final TokenType HASH = new TokenType.con2('HASH', 33, null, "#");
  static final TokenType INDEX = new TokenType.con2('INDEX', 34, TokenClass.UNARY_POSTFIX_OPERATOR, "[]");
  static final TokenType INDEX_EQ = new TokenType.con2('INDEX_EQ', 35, TokenClass.UNARY_POSTFIX_OPERATOR, "[]=");
  static final TokenType IS = new TokenType.con2('IS', 36, TokenClass.RELATIONAL_OPERATOR, "is");
  static final TokenType LT = new TokenType.con2('LT', 37, TokenClass.RELATIONAL_OPERATOR, "<");
  static final TokenType LT_EQ = new TokenType.con2('LT_EQ', 38, TokenClass.RELATIONAL_OPERATOR, "<=");
  static final TokenType LT_LT = new TokenType.con2('LT_LT', 39, TokenClass.SHIFT_OPERATOR, "<<");
  static final TokenType LT_LT_EQ = new TokenType.con2('LT_LT_EQ', 40, TokenClass.ASSIGNMENT_OPERATOR, "<<=");
  static final TokenType MINUS = new TokenType.con2('MINUS', 41, TokenClass.ADDITIVE_OPERATOR, "-");
  static final TokenType MINUS_EQ = new TokenType.con2('MINUS_EQ', 42, TokenClass.ASSIGNMENT_OPERATOR, "-=");
  static final TokenType MINUS_MINUS = new TokenType.con2('MINUS_MINUS', 43, TokenClass.UNARY_PREFIX_OPERATOR, "--");
  static final TokenType OPEN_CURLY_BRACKET = new TokenType.con2('OPEN_CURLY_BRACKET', 44, null, "{");
  static final TokenType OPEN_PAREN = new TokenType.con2('OPEN_PAREN', 45, TokenClass.UNARY_POSTFIX_OPERATOR, "(");
  static final TokenType OPEN_SQUARE_BRACKET = new TokenType.con2('OPEN_SQUARE_BRACKET', 46, TokenClass.UNARY_POSTFIX_OPERATOR, "[");
  static final TokenType PERCENT = new TokenType.con2('PERCENT', 47, TokenClass.MULTIPLICATIVE_OPERATOR, "%");
  static final TokenType PERCENT_EQ = new TokenType.con2('PERCENT_EQ', 48, TokenClass.ASSIGNMENT_OPERATOR, "%=");
  static final TokenType PERIOD = new TokenType.con2('PERIOD', 49, TokenClass.UNARY_POSTFIX_OPERATOR, ".");
  static final TokenType PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD', 50, TokenClass.CASCADE_OPERATOR, "..");
  static final TokenType PLUS = new TokenType.con2('PLUS', 51, TokenClass.ADDITIVE_OPERATOR, "+");
  static final TokenType PLUS_EQ = new TokenType.con2('PLUS_EQ', 52, TokenClass.ASSIGNMENT_OPERATOR, "+=");
  static final TokenType PLUS_PLUS = new TokenType.con2('PLUS_PLUS', 53, TokenClass.UNARY_PREFIX_OPERATOR, "++");
  static final TokenType QUESTION = new TokenType.con2('QUESTION', 54, TokenClass.CONDITIONAL_OPERATOR, "?");
  static final TokenType SEMICOLON = new TokenType.con2('SEMICOLON', 55, null, ";");
  static final TokenType SLASH = new TokenType.con2('SLASH', 56, TokenClass.MULTIPLICATIVE_OPERATOR, "/");
  static final TokenType SLASH_EQ = new TokenType.con2('SLASH_EQ', 57, TokenClass.ASSIGNMENT_OPERATOR, "/=");
  static final TokenType STAR = new TokenType.con2('STAR', 58, TokenClass.MULTIPLICATIVE_OPERATOR, "*");
  static final TokenType STAR_EQ = new TokenType.con2('STAR_EQ', 59, TokenClass.ASSIGNMENT_OPERATOR, "*=");
  static final TokenType STRING_INTERPOLATION_EXPRESSION = new TokenType.con2('STRING_INTERPOLATION_EXPRESSION', 60, null, "\${");
  static final TokenType STRING_INTERPOLATION_IDENTIFIER = new TokenType.con2('STRING_INTERPOLATION_IDENTIFIER', 61, null, "\$");
  static final TokenType TILDE = new TokenType.con2('TILDE', 62, TokenClass.UNARY_PREFIX_OPERATOR, "~");
  static final TokenType TILDE_SLASH = new TokenType.con2('TILDE_SLASH', 63, TokenClass.MULTIPLICATIVE_OPERATOR, "~/");
  static final TokenType TILDE_SLASH_EQ = new TokenType.con2('TILDE_SLASH_EQ', 64, TokenClass.ASSIGNMENT_OPERATOR, "~/=");
  static final TokenType BACKPING = new TokenType.con2('BACKPING', 65, null, "`");
  static final TokenType BACKSLASH = new TokenType.con2('BACKSLASH', 66, null, "\\");
  static final TokenType PERIOD_PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD_PERIOD', 67, null, "...");
  static final List<TokenType> values = [
      EOF,
      DOUBLE,
      HEXADECIMAL,
      IDENTIFIER,
      INT,
      KEYWORD,
      MULTI_LINE_COMMENT,
      SCRIPT_TAG,
      SINGLE_LINE_COMMENT,
      STRING,
      AMPERSAND,
      AMPERSAND_AMPERSAND,
      AMPERSAND_EQ,
      AT,
      BANG,
      BANG_EQ,
      BAR,
      BAR_BAR,
      BAR_EQ,
      COLON,
      COMMA,
      CARET,
      CARET_EQ,
      CLOSE_CURLY_BRACKET,
      CLOSE_PAREN,
      CLOSE_SQUARE_BRACKET,
      EQ,
      EQ_EQ,
      FUNCTION,
      GT,
      GT_EQ,
      GT_GT,
      GT_GT_EQ,
      HASH,
      INDEX,
      INDEX_EQ,
      IS,
      LT,
      LT_EQ,
      LT_LT,
      LT_LT_EQ,
      MINUS,
      MINUS_EQ,
      MINUS_MINUS,
      OPEN_CURLY_BRACKET,
      OPEN_PAREN,
      OPEN_SQUARE_BRACKET,
      PERCENT,
      PERCENT_EQ,
      PERIOD,
      PERIOD_PERIOD,
      PLUS,
      PLUS_EQ,
      PLUS_PLUS,
      QUESTION,
      SEMICOLON,
      SLASH,
      SLASH_EQ,
      STAR,
      STAR_EQ,
      STRING_INTERPOLATION_EXPRESSION,
      STRING_INTERPOLATION_IDENTIFIER,
      TILDE,
      TILDE_SLASH,
      TILDE_SLASH_EQ,
      BACKPING,
      BACKSLASH,
      PERIOD_PERIOD_PERIOD];

  /**
   * The class of the token.
   */
  TokenClass _tokenClass;

  /**
   * The lexeme that defines this type of token, or `null` if there is more than one possible
   * lexeme for this type of token.
   */
  String lexeme;
  TokenType.con1(String name, int ordinal) : this.con2(name, ordinal, TokenClass.NO_CLASS, null);
  TokenType.con2(String name, int ordinal, TokenClass tokenClass, String lexeme) : super(name, ordinal) {
    this._tokenClass = tokenClass == null ? TokenClass.NO_CLASS : tokenClass;
    this.lexeme = lexeme;
  }

  /**
   * Return the precedence of the token, or `0` if the token does not represent an operator.
   *
   * @return the precedence of the token
   */
  int get precedence => _tokenClass.precedence;

  /**
   * Return `true` if this type of token represents an additive operator.
   *
   * @return `true` if this type of token represents an additive operator
   */
  bool get isAdditiveOperator => identical(_tokenClass, TokenClass.ADDITIVE_OPERATOR);

  /**
   * Return `true` if this type of token represents an assignment operator.
   *
   * @return `true` if this type of token represents an assignment operator
   */
  bool get isAssignmentOperator => identical(_tokenClass, TokenClass.ASSIGNMENT_OPERATOR);

  /**
   * Return `true` if this type of token represents an associative operator. An associative
   * operator is an operator for which the following equality is true:
   * `(a * b) * c == a * (b * c)`. In other words, if the result of applying the operator to
   * multiple operands does not depend on the order in which those applications occur.
   *
   * Note: This method considers the logical-and and logical-or operators to be associative, even
   * though the order in which the application of those operators can have an effect because
   * evaluation of the right-hand operand is conditional.
   *
   * @return `true` if this type of token represents an associative operator
   */
  bool get isAssociativeOperator => identical(this, AMPERSAND) || identical(this, AMPERSAND_AMPERSAND) || identical(this, BAR) || identical(this, BAR_BAR) || identical(this, CARET) || identical(this, PLUS) || identical(this, STAR);

  /**
   * Return `true` if this type of token represents an equality operator.
   *
   * @return `true` if this type of token represents an equality operator
   */
  bool get isEqualityOperator => identical(_tokenClass, TokenClass.EQUALITY_OPERATOR);

  /**
   * Return `true` if this type of token represents an increment operator.
   *
   * @return `true` if this type of token represents an increment operator
   */
  bool get isIncrementOperator => identical(lexeme, "++") || identical(lexeme, "--");

  /**
   * Return `true` if this type of token represents a multiplicative operator.
   *
   * @return `true` if this type of token represents a multiplicative operator
   */
  bool get isMultiplicativeOperator => identical(_tokenClass, TokenClass.MULTIPLICATIVE_OPERATOR);

  /**
   * Return `true` if this token type represents an operator.
   *
   * @return `true` if this token type represents an operator
   */
  bool get isOperator => _tokenClass != TokenClass.NO_CLASS && this != OPEN_PAREN && this != OPEN_SQUARE_BRACKET && this != PERIOD;

  /**
   * Return `true` if this type of token represents a relational operator.
   *
   * @return `true` if this type of token represents a relational operator
   */
  bool get isRelationalOperator => identical(_tokenClass, TokenClass.RELATIONAL_OPERATOR);

  /**
   * Return `true` if this type of token represents a shift operator.
   *
   * @return `true` if this type of token represents a shift operator
   */
  bool get isShiftOperator => identical(_tokenClass, TokenClass.SHIFT_OPERATOR);

  /**
   * Return `true` if this type of token represents a unary postfix operator.
   *
   * @return `true` if this type of token represents a unary postfix operator
   */
  bool get isUnaryPostfixOperator => identical(_tokenClass, TokenClass.UNARY_POSTFIX_OPERATOR);

  /**
   * Return `true` if this type of token represents a unary prefix operator.
   *
   * @return `true` if this type of token represents a unary prefix operator
   */
  bool get isUnaryPrefixOperator => identical(_tokenClass, TokenClass.UNARY_PREFIX_OPERATOR);

  /**
   * Return `true` if this token type represents an operator that can be defined by users.
   *
   * @return `true` if this token type represents an operator that can be defined by users
   */
  bool get isUserDefinableOperator => identical(lexeme, "==") || identical(lexeme, "~") || identical(lexeme, "[]") || identical(lexeme, "[]=") || identical(lexeme, "*") || identical(lexeme, "/") || identical(lexeme, "%") || identical(lexeme, "~/") || identical(lexeme, "+") || identical(lexeme, "-") || identical(lexeme, "<<") || identical(lexeme, ">>") || identical(lexeme, ">=") || identical(lexeme, ">") || identical(lexeme, "<=") || identical(lexeme, "<") || identical(lexeme, "&") || identical(lexeme, "^") || identical(lexeme, "|");
}
class TokenType_EOF extends TokenType {
  TokenType_EOF(String name, int ordinal, TokenClass arg0, String arg1) : super.con2(name, ordinal, arg0, arg1);
  String toString() => "-eof-";
}