// 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.html;

import 'dart:collection';
import 'java_core.dart';
import 'source.dart';
import 'error.dart';
import 'instrumentation.dart';
import 'element.dart' show HtmlElementImpl;

/**
 * Instances of the class {@code 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.html
 */
class Token {
  /**
   * 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;
  /**
   * The type of the token.
   */
  TokenType _type;
  /**
   * The lexeme represented by this token.
   */
  String _value;
  /**
   * Initialize a newly created token.
   * @param type the token type (not {@code null})
   * @param offset the offset from the beginning of the file to the first character in the token
   */
  Token.con1(TokenType type, int offset) {
    _jtd_constructor_147_impl(type, offset);
  }
  _jtd_constructor_147_impl(TokenType type, int offset) {
    _jtd_constructor_148_impl(type, offset, type.lexeme);
  }
  /**
   * Initialize a newly created token.
   * @param type the token type (not {@code null})
   * @param offset the offset from the beginning of the file to the first character in the token
   * @param value the lexeme represented by this token (not {@code null})
   */
  Token.con2(TokenType type4, int offset3, String value7) {
    _jtd_constructor_148_impl(type4, offset3, value7);
  }
  _jtd_constructor_148_impl(TokenType type4, int offset3, String value7) {
    this._type = type4;
    this._value = value7;
    this._offset = offset3;
  }
  /**
   * 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 (not {@code null})
   */
  String get lexeme => _value;
  /**
   * Return the next token in the token stream.
   * @return the next token in the token stream
   */
  Token get next => _next;
  /**
   * Return the offset from the beginning of the file to the first character in the token.
   * @return the offset from the beginning of the file to the first character in the token
   */
  int get offset => _offset;
  /**
   * Return the previous token in the token stream.
   * @return the previous token in the token stream
   */
  Token get previous => _previous;
  /**
   * Answer the token type for the receiver.
   * @return the token type (not {@code null})
   */
  TokenType get type => _type;
  /**
   * Return {@code 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 ({@code 0}).
   * @return {@code true} if this token is a synthetic token
   */
  bool isSynthetic() => length == 0;
  /**
   * 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;
  }
  String toString() => lexeme;
  /**
   * Set the previous token in the token stream to the given token.
   * @param previous the previous token in the token stream
   */
  void set previous(Token previous2) {
    this._previous = previous2;
  }
}
/**
 * Instances of {@code HtmlParseResult} hold the result of parsing an HTML file.
 * @coverage dart.engine.html
 */
class HtmlParseResult extends HtmlScanResult {
  /**
   * The unit containing the parsed information (not {@code null}).
   */
  HtmlUnit _unit;
  HtmlParseResult(Token token, List<int> lineStarts, HtmlUnit unit) : super(token, lineStarts) {
    this._unit = unit;
  }
  /**
   * Answer the unit generated by parsing the source
   * @return the unit (not {@code null})
   */
  HtmlUnit get htmlUnit => _unit;
}
/**
 * Instances of the class {@code RecursiveXmlVisitor} implement an XML visitor that will recursively
 * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
 * a {@link XmlTagNode} will also cause all of the contained {@link XmlAttributeNode}s and{@link XmlTagNode}s to be visited.
 * <p>
 * Subclasses that override a visit method must either invoke the overridden visit method or must
 * explicitly ask the visited node to visit its children. Failure to do so will cause the children
 * of the visited node to not be visited.
 * @coverage dart.engine.html
 */
class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
  R visitHtmlUnit(HtmlUnit node) {
    node.visitChildren(this);
    return null;
  }
  R visitXmlAttributeNode(XmlAttributeNode node) {
    node.visitChildren(this);
    return null;
  }
  R visitXmlTagNode(XmlTagNode node) {
    node.visitChildren(this);
    return null;
  }
}
/**
 * The abstract class {@code XmlNode} defines behavior common to all XML/HTML nodes.
 * @coverage dart.engine.html
 */
abstract class XmlNode {
  /**
   * The parent of the node, or {@code null} if the node is the root of an AST structure.
   */
  XmlNode _parent;
  /**
   * Use the given visitor to visit this node.
   * @param visitor the visitor that will visit this node
   * @return the value returned by the visitor as a result of visiting this node
   */
  accept(XmlVisitor visitor);
  /**
   * Return the first token included in this node's source range.
   * @return the first token or {@code null} if none
   */
  Token get beginToken;
  /**
   * Return the offset of the character immediately following the last character of this node's
   * source range. This is equivalent to {@code node.getOffset() + node.getLength()}. For an html
   * unit this will be equal to the length of the unit's source.
   * @return the offset of the character just past the node's source range
   */
  int get end => offset + length;
  /**
   * Return the last token included in this node's source range.
   * @return the last token or {@code null} if none
   */
  Token get endToken;
  /**
   * 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 {
    Token beginToken4 = beginToken;
    Token endToken4 = endToken;
    if (beginToken4 == null || endToken4 == null) {
      return -1;
    }
    return endToken4.offset + endToken4.length - beginToken4.offset;
  }
  /**
   * Return the offset from the beginning of the file to the first character in the node's source
   * range.
   * @return the offset from the beginning of the file to the first character in the node's source
   * range
   */
  int get offset {
    Token beginToken5 = beginToken;
    if (beginToken5 == null) {
      return -1;
    }
    return beginToken.offset;
  }
  /**
   * Return this node's parent node, or {@code null} if this node is the root of an AST structure.
   * <p>
   * Note that the relationship between an AST node and its parent node may change over the lifetime
   * of a node.
   * @return the parent of this node, or {@code null} if none
   */
  XmlNode get parent => _parent;
  /**
   * Use the given visitor to visit all of the children of this node. The children will be visited
   * in source order.
   * @param visitor the visitor that will be used to visit the children of this node
   */
  void visitChildren(XmlVisitor<Object> visitor);
  /**
   * Make this node the parent of the given child nodes.
   * @param children the nodes that will become the children of this node
   * @return the nodes that were made children of this node
   */
  List<XmlNode> becomeParentOf(List<XmlNode> children) {
    if (children != null) {
      for (JavaIterator<XmlNode> iter = new JavaIterator(children); iter.hasNext;) {
        XmlNode node = iter.next();
        node.parent = this;
      }
    }
    return children;
  }
  /**
   * Make this node the parent of the given child node.
   * @param child the node that will become a child of this node
   * @return the node that was made a child of this node
   */
  XmlNode becomeParentOf2(XmlNode child) {
    if (child != null) {
      XmlNode node = child;
      node.parent = this;
    }
    return child;
  }
  /**
   * Set the parent of this node to the given node.
   * @param newParent the node that is to be made the parent of this node
   */
  void set parent(XmlNode newParent) {
    _parent = newParent;
  }
}
/**
 * Instances of the class {@code SimpleXmlVisitor} implement an AST visitor that will do nothing
 * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
 * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
 * structure) and that only need to visit a small number of node types.
 */
class SimpleXmlVisitor<R> implements XmlVisitor<R> {
  R visitHtmlUnit(HtmlUnit htmlUnit) => null;
  R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
  R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
}
/**
 * The abstract class {@code AbstractScanner} implements a scanner for HTML code. Subclasses are
 * required to implement the interface used to access the characters being scanned.
 * @coverage dart.engine.html
 */
abstract class AbstractScanner {
  static List<String> _NO_PASS_THROUGH_ELEMENTS = <String> [];
  /**
   * The source being scanned.
   */
  Source _source;
  /**
   * The token pointing to the head of the linked list of tokens.
   */
  Token _tokens;
  /**
   * The last token that was scanned.
   */
  Token _tail;
  /**
   * A list containing the offsets of the first character of each line in the source code.
   */
  List<int> _lineStarts = new List<int>();
  /**
   * An array of element tags for which the content between tags should be consider a single token.
   */
  List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
  /**
   * Initialize a newly created scanner.
   * @param source the source being scanned
   */
  AbstractScanner(Source source) {
    this._source = source;
    _tokens = new Token.con1(TokenType.EOF, -1);
    _tokens.setNext(_tokens);
    _tail = _tokens;
    recordStartOfLine();
  }
  /**
   * 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;
  /**
   * Answer the source being scanned.
   * @return the source or {@code null} if undefined
   */
  Source get source => _source;
  /**
   * Set array of element tags for which the content between tags should be consider a single token.
   */
  void set passThroughElements(List<String> passThroughElements2) {
    this._passThroughElements = passThroughElements2 != null ? passThroughElements2 : _NO_PASS_THROUGH_ELEMENTS;
  }
  /**
   * 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() {
    scan();
    appendEofToken();
    return firstToken();
  }
  /**
   * 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 appendEofToken() {
    Token eofToken = new Token.con1(TokenType.EOF, offset);
    eofToken.setNext(eofToken);
    _tail = _tail.setNext(eofToken);
  }
  Token emit(Token token) {
    _tail.setNext(token);
    _tail = token;
    return token;
  }
  Token emit2(TokenType type, int start) => emit(new Token.con1(type, start));
  Token emit3(TokenType type, int start, int count) => emit(new Token.con2(type, start, getString(start, count)));
  Token firstToken() => _tokens.next;
  int recordStartOfLineAndAdvance(int c) {
    if (c == 0xD) {
      c = advance();
      if (c == 0xA) {
        c = advance();
      }
      recordStartOfLine();
    } else if (c == 0xA) {
      c = advance();
      recordStartOfLine();
    } else {
      c = advance();
    }
    return c;
  }
  void scan() {
    bool inBrackets = false;
    bool passThrough = false;
    int c = advance();
    while (c >= 0) {
      int start = offset;
      if (c == 0x3C) {
        c = advance();
        if (c == 0x21) {
          c = advance();
          if (c == 0x2D && peek() == 0x2D) {
            c = advance();
            int dashCount = 1;
            while (c >= 0) {
              if (c == 0x2D) {
                dashCount++;
              } else if (c == 0x3E && dashCount >= 2) {
                c = advance();
                break;
              } else {
                dashCount = 0;
              }
              c = recordStartOfLineAndAdvance(c);
            }
            emit3(TokenType.COMMENT, start, -1);
            if (_tail.length < 7) {
            }
          } else {
            while (c >= 0) {
              if (c == 0x3E) {
                c = advance();
                break;
              }
              c = recordStartOfLineAndAdvance(c);
            }
            emit3(TokenType.DECLARATION, start, -1);
            if (!_tail.lexeme.endsWith(">")) {
            }
          }
        } else if (c == 0x3F) {
          while (c >= 0) {
            if (c == 0x3F) {
              c = advance();
              if (c == 0x3E) {
                c = advance();
                break;
              }
            } else {
              c = recordStartOfLineAndAdvance(c);
            }
          }
          emit3(TokenType.DIRECTIVE, start, -1);
          if (_tail.length < 4) {
          }
        } else if (c == 0x2F) {
          emit2(TokenType.LT_SLASH, start);
          inBrackets = true;
          c = advance();
        } else {
          inBrackets = true;
          emit2(TokenType.LT, start);
          while (Character.isWhitespace(c)) {
            c = recordStartOfLineAndAdvance(c);
          }
          if (Character.isLetterOrDigit(c)) {
            int tagStart = offset;
            c = advance();
            while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
              c = advance();
            }
            emit3(TokenType.TAG, tagStart, -1);
            String tag = _tail.lexeme;
            for (String str in _passThroughElements) {
              if (str == tag) {
                passThrough = true;
                break;
              }
            }
          }
        }
      } else if (c == 0x3E) {
        emit2(TokenType.GT, start);
        inBrackets = false;
        c = advance();
        if (passThrough) {
          while (c >= 0 && (c != 0x3C || peek() != 0x2F)) {
            c = recordStartOfLineAndAdvance(c);
          }
          if (start + 1 < offset) {
            emit3(TokenType.TEXT, start + 1, -1);
          }
          passThrough = false;
        }
      } else if (c == 0x2F && peek() == 0x3E) {
        advance();
        emit2(TokenType.SLASH_GT, start);
        inBrackets = false;
        c = advance();
      } else if (!inBrackets) {
        c = recordStartOfLineAndAdvance(c);
        while (c != 0x3C && c >= 0) {
          c = recordStartOfLineAndAdvance(c);
        }
        emit3(TokenType.TEXT, start, -1);
      } else if (c == 0x22 || c == 0x27) {
        int endQuote = c;
        c = advance();
        while (c >= 0) {
          if (c == endQuote) {
            c = advance();
            break;
          }
          c = recordStartOfLineAndAdvance(c);
        }
        emit3(TokenType.STRING, start, -1);
      } else if (c == 0x3D) {
        emit2(TokenType.EQ, start);
        c = advance();
      } else if (Character.isWhitespace(c)) {
        do {
          c = recordStartOfLineAndAdvance(c);
        } while (Character.isWhitespace(c));
      } else if (Character.isLetterOrDigit(c)) {
        c = advance();
        while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
          c = advance();
        }
        emit3(TokenType.TAG, start, -1);
      } else {
        emit3(TokenType.TEXT, start, 0);
        c = advance();
      }
    }
  }
}
/**
 * Instances of {@code HtmlScanResult} hold the result of scanning an HTML file.
 * @coverage dart.engine.html
 */
class HtmlScanResult {
  /**
   * The first token in the token stream (not {@code null}).
   */
  Token _token;
  /**
   * The line start information that was produced.
   */
  List<int> _lineStarts;
  HtmlScanResult(Token token, List<int> lineStarts) {
    this._token = token;
    this._lineStarts = lineStarts;
  }
  /**
   * Answer the line start information that was produced.
   * @return an array of line starts (not {@code null})
   */
  List<int> get lineStarts => _lineStarts;
  /**
   * Answer the first token in the token stream.
   * @return the token (not {@code null})
   */
  Token get token => _token;
}
/**
 * Instances of the class {@code StringScanner} implement a scanner that reads from a string. The
 * scanning logic is in the superclass.
 * @coverage dart.engine.html
 */
class StringScanner extends AbstractScanner {
  /**
   * 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
   */
  StringScanner(Source source, String string) : super(source) {
    this._string = string;
    this._stringLength = string.length;
    this._charOffset = -1;
  }
  int get offset => _charOffset;
  void set offset(int offset12) {
    _charOffset = offset12;
  }
  int advance() {
    if (++_charOffset < _stringLength) {
      return _string.codeUnitAt(_charOffset);
    }
    _charOffset = _stringLength;
    return -1;
  }
  String getString(int start, int endDelta) => _string.substring(start, _charOffset + 1 + endDelta);
  int peek() {
    if (_charOffset + 1 < _stringLength) {
      return _string.codeUnitAt(_charOffset + 1);
    }
    return -1;
  }
}
/**
 * Instances of the class {@code CharBufferScanner} implement a scanner that reads from a character
 * buffer. The scanning logic is in the superclass.
 * @coverage dart.engine.html
 */
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
   */
  CharBufferScanner(Source source, CharBuffer buffer) : super(source) {
    this._buffer = buffer;
    this._bufferLength = buffer.length();
    this._charOffset = -1;
  }
  int get offset => _charOffset;
  int advance() {
    if (++_charOffset < _bufferLength) {
      return _buffer.charAt(_charOffset);
    }
    _charOffset = _bufferLength;
    return -1;
  }
  String getString(int start, int endDelta) => _buffer.subSequence(start, _charOffset + 1 + endDelta).toString();
  int peek() {
    if (_charOffset + 1 < _bufferLength) {
      return _buffer.charAt(_charOffset + 1);
    }
    return -1;
  }
}
/**
 * The enumeration {@code TokenType} defines the types of tokens that can be returned by the
 * scanner.
 * @coverage dart.engine.html
 */
class TokenType {
  /**
   * The type of the token that marks the end of the input.
   */
  static final TokenType EOF = new TokenType_EOF('EOF', 0, "");
  static final TokenType EQ = new TokenType('EQ', 1, "=");
  static final TokenType GT = new TokenType('GT', 2, ">");
  static final TokenType LT_SLASH = new TokenType('LT_SLASH', 3, "</");
  static final TokenType LT = new TokenType('LT', 4, "<");
  static final TokenType SLASH_GT = new TokenType('SLASH_GT', 5, "/>");
  static final TokenType COMMENT = new TokenType('COMMENT', 6, null);
  static final TokenType DECLARATION = new TokenType('DECLARATION', 7, null);
  static final TokenType DIRECTIVE = new TokenType('DIRECTIVE', 8, null);
  static final TokenType STRING = new TokenType('STRING', 9, null);
  static final TokenType TAG = new TokenType('TAG', 10, null);
  static final TokenType TEXT = new TokenType('TEXT', 11, null);
  static final List<TokenType> values = [EOF, EQ, GT, LT_SLASH, LT, SLASH_GT, COMMENT, DECLARATION, DIRECTIVE, STRING, TAG, TEXT];
  final String __name;
  final int __ordinal;
  int get ordinal => __ordinal;
  /**
   * The lexeme that defines this type of token, or {@code null} if there is more than one possible
   * lexeme for this type of token.
   */
  String _lexeme;
  TokenType(this.__name, this.__ordinal, String lexeme) {
    this._lexeme = lexeme;
  }
  /**
   * Return the lexeme that defines this type of token, or {@code null} if there is more than one
   * possible lexeme for this type of token.
   * @return the lexeme that defines this type of token
   */
  String get lexeme => _lexeme;
  String toString() => __name;
}
class TokenType_EOF extends TokenType {
  TokenType_EOF(String ___name, int ___ordinal, String arg0) : super(___name, ___ordinal, arg0);
  String toString() => "-eof-";
}
/**
 * Instances of {@code XmlAttributeNode} represent name/value pairs owned by an {@link XmlTagNode}.
 * @coverage dart.engine.html
 */
class XmlAttributeNode extends XmlNode {
  Token _name;
  Token _equals;
  Token _value;
  /**
   * Construct a new instance representing an XML attribute.
   * @param name the name token (not {@code null}). This may be a zero length token if the attribute
   * is badly formed.
   * @param equals the equals sign or {@code null} if none
   * @param value the value token (not {@code null})
   */
  XmlAttributeNode(Token name, Token equals, Token value) {
    this._name = name;
    this._equals = equals;
    this._value = value;
  }
  accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
  Token get beginToken => _name;
  Token get endToken => _value;
  /**
   * Answer the equals sign token that appears between the name and value tokens. This may be{@code null} if the attribute is badly formed.
   * @return the token or {@code null} if there is no equals sign between the name and value
   */
  Token get equals => _equals;
  /**
   * Answer the attribute name. This may be a zero length token if the attribute is badly formed.
   * @return the name (not {@code null})
   */
  Token get name => _name;
  /**
   * Answer the lexeme for the value token without the leading and trailing quotes.
   * @return the text or {@code null} if the value is not specified
   */
  String get text {
    if (_value == null) {
      return null;
    }
    String text = _value.lexeme;
    int len = text.length;
    if (len > 0) {
      if (text.codeUnitAt(0) == 0x22) {
        if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
          return text.substring(1, len - 1);
        } else {
          return text.substring(1);
        }
      } else if (text.codeUnitAt(0) == 0x27) {
        if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
          return text.substring(1, len - 1);
        } else {
          return text.substring(1);
        }
      }
    }
    return text;
  }
  /**
   * Answer the attribute value. A properly formed value will start and end with matching quote
   * characters, but the value returned may not be properly formed.
   * @return the value or {@code null} if this represents a badly formed attribute
   */
  Token get value => _value;
  void visitChildren(XmlVisitor<Object> visitor) {
  }
}
/**
 * The interface {@code XmlVisitor} defines the behavior of objects that can be used to visit an{@link XmlNode} structure.
 * @coverage dart.engine.html
 */
abstract class XmlVisitor<R> {
  R visitHtmlUnit(HtmlUnit htmlUnit);
  R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
  R visitXmlTagNode(XmlTagNode xmlTagNode);
}
/**
 * Instances of {@code HtmlScanner} receive and scan HTML content from a {@link Source}.<br/>
 * For example, the following code scans HTML source and returns the result:
 * <pre>
 * HtmlScanner scanner = new HtmlScanner(source);
 * source.getContents(scanner);
 * return scanner.getResult();
 * </pre>
 * @coverage dart.engine.html
 */
class HtmlScanner implements Source_ContentReceiver {
  List<String> _SCRIPT_TAG = <String> ["script"];
  /**
   * The source being scanned (not {@code null})
   */
  Source _source;
  /**
   * The scanner used to scan the source
   */
  AbstractScanner _scanner;
  /**
   * The first token in the token stream.
   */
  Token _token;
  /**
   * Construct a new instance to scan the specified source.
   * @param source the source to be scanned (not {@code null})
   */
  HtmlScanner(Source source) {
    this._source = source;
  }
  accept(CharBuffer contents) {
    _scanner = new CharBufferScanner(_source, contents);
    _scanner.passThroughElements = _SCRIPT_TAG;
    _token = _scanner.tokenize();
  }
  void accept2(String contents) {
    _scanner = new StringScanner(_source, contents);
    _scanner.passThroughElements = _SCRIPT_TAG;
    _token = _scanner.tokenize();
  }
  /**
   * Answer the result of scanning the source
   * @return the result (not {@code null})
   */
  HtmlScanResult get result => new HtmlScanResult(_token, _scanner.lineStarts);
}
/**
 * Instances of the class {@code XmlParser} are used to parse tokens into a AST structure comprised
 * of {@link XmlNode}s.
 * @coverage dart.engine.html
 */
class XmlParser {
  /**
   * The source being parsed.
   */
  Source _source;
  /**
   * The next token to be parsed.
   */
  Token _currentToken;
  /**
   * Construct a parser for the specified source.
   * @param source the source being parsed
   */
  XmlParser(Source source) {
    this._source = source;
  }
  /**
   * Answer the source being parsed.
   * @return the source
   */
  Source get source => _source;
  /**
   * Answer {@code true} if the specified tag is self closing and thus should never have content or
   * child tag nodes.
   * @param tag the tag (not {@code null})
   * @return {@code true} if self closing
   */
  bool isSelfClosing(Token tag) => false;
  /**
   * Parse the entire token stream and in the process, advance the current token to the end of the
   * token stream.
   * @return the list of tag nodes found (not {@code null}, contains no {@code null})
   */
  List<XmlTagNode> parseTopTagNodes(Token firstToken) {
    _currentToken = firstToken;
    List<XmlTagNode> tagNodes = new List<XmlTagNode>();
    while (true) {
      while (true) {
        if (_currentToken.type == TokenType.LT) {
          tagNodes.add(parseTagNode());
        } else if (_currentToken.type == TokenType.DECLARATION || _currentToken.type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) {
          _currentToken = _currentToken.next;
        } else if (_currentToken.type == TokenType.EOF) {
          return tagNodes;
        } else {
          reportUnexpectedToken();
          _currentToken = _currentToken.next;
        }
        break;
      }
    }
  }
  /**
   * Answer the current token.
   * @return the current token
   */
  Token get currentToken => _currentToken;
  /**
   * Insert a synthetic token of the specified type before the current token
   * @param type the type of token to be inserted (not {@code null})
   * @return the synthetic token that was inserted (not {@code null})
   */
  Token insertSyntheticToken(TokenType type) {
    Token token = new Token.con2(type, _currentToken.offset, "");
    _currentToken.previous.setNext(token);
    token.setNext(_currentToken);
    return token;
  }
  /**
   * Parse the token stream for an attribute. This method advances the current token over the
   * attribute, but should not be called if the {@link #currentToken} is not {@link TokenType#TAG}.
   * @return the attribute (not {@code null})
   */
  XmlAttributeNode parseAttribute() {
    Token name = _currentToken;
    _currentToken = _currentToken.next;
    Token equals;
    if (identical(_currentToken.type, TokenType.EQ)) {
      equals = _currentToken;
      _currentToken = _currentToken.next;
    } else {
      reportUnexpectedToken();
      equals = insertSyntheticToken(TokenType.EQ);
    }
    Token value;
    if (identical(_currentToken.type, TokenType.STRING)) {
      value = _currentToken;
      _currentToken = _currentToken.next;
    } else {
      reportUnexpectedToken();
      value = insertSyntheticToken(TokenType.STRING);
    }
    return new XmlAttributeNode(name, equals, value);
  }
  /**
   * Parse the stream for a sequence of attributes. This method advances the current token to the
   * next {@link TokenType#GT}, {@link TokenType#SLASH_GT}, or {@link TokenType#EOF}.
   * @return a collection of zero or more attributes (not {@code null}, contains no {@code null}s)
   */
  List<XmlAttributeNode> parseAttributes() {
    TokenType type11 = _currentToken.type;
    if (identical(type11, TokenType.GT) || identical(type11, TokenType.SLASH_GT) || identical(type11, TokenType.EOF)) {
      return XmlTagNode.NO_ATTRIBUTES;
    }
    List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
    while (true) {
      while (true) {
        if (_currentToken.type == TokenType.GT || _currentToken.type == TokenType.SLASH_GT || _currentToken.type == TokenType.EOF) {
          return attributes;
        } else if (_currentToken.type == TokenType.TAG) {
          attributes.add(parseAttribute());
        } else {
          reportUnexpectedToken();
          _currentToken = _currentToken.next;
        }
        break;
      }
    }
  }
  /**
   * Parse the stream for a sequence of tag nodes existing within a parent tag node. This method
   * advances the current token to the next {@link TokenType#LT_SLASH} or {@link TokenType#EOF}.
   * @return a list of nodes (not {@code null}, contains no {@code null}s)
   */
  List<XmlTagNode> parseChildTagNodes() {
    TokenType type12 = _currentToken.type;
    if (identical(type12, TokenType.LT_SLASH) || identical(type12, TokenType.EOF)) {
      return XmlTagNode.NO_TAG_NODES;
    }
    List<XmlTagNode> nodes = new List<XmlTagNode>();
    while (true) {
      while (true) {
        if (_currentToken.type == TokenType.LT) {
          nodes.add(parseTagNode());
        } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.type == TokenType.EOF) {
          return nodes;
        } else if (_currentToken.type == TokenType.COMMENT) {
          _currentToken = _currentToken.next;
        } else {
          reportUnexpectedToken();
          _currentToken = _currentToken.next;
        }
        break;
      }
    }
  }
  /**
   * Parse the token stream for the next tag node. This method advances current token over the
   * parsed tag node, but should only be called if the current token is {@link TokenType#LT}
   * @return the tag node or {@code null} if none found
   */
  XmlTagNode parseTagNode() {
    Token nodeStart = _currentToken;
    _currentToken = _currentToken.next;
    Token tag;
    if (identical(_currentToken.type, TokenType.TAG)) {
      tag = _currentToken;
      _currentToken = _currentToken.next;
    } else {
      reportUnexpectedToken();
      tag = insertSyntheticToken(TokenType.TAG);
    }
    List<XmlAttributeNode> attributes = parseAttributes();
    Token attributeEnd;
    if (identical(_currentToken.type, TokenType.GT) || identical(_currentToken.type, TokenType.SLASH_GT)) {
      attributeEnd = _currentToken;
      _currentToken = _currentToken.next;
    } else {
      reportUnexpectedToken();
      attributeEnd = insertSyntheticToken(TokenType.SLASH_GT);
    }
    if (identical(attributeEnd.type, TokenType.SLASH_GT) || isSelfClosing(tag)) {
      return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode.NO_TAG_NODES, _currentToken, null, attributeEnd);
    }
    List<XmlTagNode> tagNodes = parseChildTagNodes();
    Token contentEnd;
    if (identical(_currentToken.type, TokenType.LT_SLASH)) {
      contentEnd = _currentToken;
      _currentToken = _currentToken.next;
    } else {
      reportUnexpectedToken();
      contentEnd = insertSyntheticToken(TokenType.LT_SLASH);
    }
    Token closingTag;
    if (identical(_currentToken.type, TokenType.TAG)) {
      closingTag = _currentToken;
      _currentToken = _currentToken.next;
    } else {
      reportUnexpectedToken();
      closingTag = insertSyntheticToken(TokenType.TAG);
    }
    Token nodeEnd;
    if (identical(_currentToken.type, TokenType.GT)) {
      nodeEnd = _currentToken;
      _currentToken = _currentToken.next;
    } else {
      reportUnexpectedToken();
      nodeEnd = insertSyntheticToken(TokenType.GT);
    }
    return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
  }
  /**
   * Report the current token as unexpected
   */
  void reportUnexpectedToken() {
  }
}
/**
 * Instances of {@code XmlTagNode} represent XML or HTML elements such as {@code <p>} and{@code <body foo="bar"> ... </body>}.
 * @coverage dart.engine.html
 */
class XmlTagNode extends XmlNode {
  /**
   * Constant representing empty list of attributes.
   */
  static List<XmlAttributeNode> NO_ATTRIBUTES = new UnmodifiableListView(new List<XmlAttributeNode>());
  /**
   * Constant representing empty list of tag nodes.
   */
  static List<XmlTagNode> NO_TAG_NODES = new UnmodifiableListView(new List<XmlTagNode>());
  /**
   * The starting {@link TokenType#LT} token (not {@code null}).
   */
  Token _nodeStart;
  /**
   * The {@link TokenType#TAG} token after the starting '&lt;' (not {@code null}).
   */
  Token _tag;
  /**
   * The attributes contained by the receiver (not {@code null}, contains no {@code null}s).
   */
  List<XmlAttributeNode> _attributes;
  /**
   * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attributes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
   */
  Token _attributeEnd;
  /**
   * The tag nodes contained in the receiver (not {@code null}, contains no {@code null}s).
   */
  List<XmlTagNode> _tagNodes;
  /**
   * The token (not {@code null}) after the content, which may be
   * <ul>
   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
   * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last node in
   * the stream {@link TokenType#LT_SLASH} token after the content, or {@code null} if there is no
   * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
   * </ul>
   */
  Token _contentEnd;
  /**
   * The closing {@link TokenType#TAG} after the child elements or {@code null} if there is no
   * content and the attributes ended with {@link TokenType#SLASH_GT}
   */
  Token _closingTag;
  /**
   * The ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not {@code null}).
   */
  Token _nodeEnd;
  /**
   * Construct a new instance representing an XML or HTML element
   * @param nodeStart the starting {@link TokenType#LT} token (not {@code null})
   * @param tag the {@link TokenType#TAG} token after the starting '&lt;' (not {@code null}).
   * @param attributes the attributes associated with this element or {@link #NO_ATTRIBUTES} (not{@code null}, contains no {@code null}s)
   * @param attributeEnd The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the
   * attributes (not {@code null}). The token may be the same token as {@link #nodeEnd} if
   * there are no child {@link #tagNodes}.
   * @param tagNodes child tag nodes of the receiver or {@link #NO_TAG_NODES} (not {@code null},
   * contains no {@code null}s)
   * @param contentEnd the token (not {@code null}) after the content, which may be
   * <ul>
   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is
   * self closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last
   * node in the stream {@link TokenType#LT_SLASH} token after the content, or {@code null}if there is no content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
   * </ul>
   * @param closingTag the closing {@link TokenType#TAG} after the child elements or {@code null} if
   * there is no content and the attributes ended with {@link TokenType#SLASH_GT}
   * @param nodeEnd the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token (not{@code null})
   */
  XmlTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, Token nodeEnd) {
    this._nodeStart = nodeStart;
    this._tag = tag;
    this._attributes = becomeParentOf(attributes);
    this._attributeEnd = attributeEnd;
    this._tagNodes = becomeParentOf(tagNodes);
    this._contentEnd = contentEnd;
    this._closingTag = closingTag;
    this._nodeEnd = nodeEnd;
  }
  accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
  /**
   * The {@link TokenType#GT} or {@link TokenType#SLASH_GT} token after the attributes (not{@code null}). The token may be the same token as {@link #nodeEnd} if there are no child{@link #tagNodes}.
   * @return the token (not {@code null})
   */
  Token get attributeEnd => _attributeEnd;
  /**
   * Answer the receiver's attributes. Callers should not manipulate the returned list to edit the
   * AST structure.
   * @return the attributes (not {@code null}, contains no {@code null}s)
   */
  List<XmlAttributeNode> get attributes => _attributes;
  Token get beginToken => _nodeStart;
  /**
   * The the closing {@link TokenType#TAG} after the child elements or {@code null} if there is no
   * content and the attributes ended with {@link TokenType#SLASH_GT}
   * @return the closing tag or {@code null}
   */
  Token get closingTag => _closingTag;
  /**
   * Answer a string representing the content contained in the receiver. This includes the textual
   * representation of any child tag nodes ({@link #getTagNodes()}). Whitespace between '&lt;',
   * '&lt;/', and '>', '/>' is discarded, but all other whitespace is preserved.
   * @return the content (not {@code null})
   */
  String get content {
    Token token = _attributeEnd.next;
    if (identical(token, _contentEnd)) {
      return "";
    }
    String content = token.lexeme;
    token = token.next;
    if (identical(token, _contentEnd)) {
      return content;
    }
    JavaStringBuilder buffer = new JavaStringBuilder();
    while (token != _contentEnd) {
      buffer.append(token.lexeme);
      token = token.next;
    }
    return buffer.toString();
  }
  /**
   * Answer the token (not {@code null}) after the content, which may be
   * <ul>
   * <li>(1) {@link TokenType#LT_SLASH} for nodes with open and close tags, or</li>
   * <li>(2) the {@link TokenType#LT} nodeStart of the next sibling node if this node is self
   * closing or the attributeEnd is {@link TokenType#SLASH_GT}, or</li>
   * <li>(3) {@link TokenType#EOF} if the node does not have a closing tag and is the last node in
   * the stream {@link TokenType#LT_SLASH} token after the content, or {@code null} if there is no
   * content and the attributes ended with {@link TokenType#SLASH_GT}.</li>
   * </ul>
   * @return the token (not {@code null})
   */
  Token get contentEnd => _contentEnd;
  Token get endToken {
    if (_nodeEnd != null) {
      return _nodeEnd;
    }
    if (_closingTag != null) {
      return _closingTag;
    }
    if (_contentEnd != null) {
      return _contentEnd;
    }
    if (!_tagNodes.isEmpty) {
      return _tagNodes[_tagNodes.length - 1].endToken;
    }
    if (_attributeEnd != null) {
      return _attributeEnd;
    }
    if (!_attributes.isEmpty) {
      return _attributes[_attributes.length - 1].endToken;
    }
    return _tag;
  }
  /**
   * Answer the ending {@link TokenType#GT} or {@link TokenType#SLASH_GT} token.
   * @return the token (not {@code null})
   */
  Token get nodeEnd => _nodeEnd;
  /**
   * Answer the starting {@link TokenType#LT} token.
   * @return the token (not {@code null})
   */
  Token get nodeStart => _nodeStart;
  /**
   * Answer the {@link TokenType#TAG} token after the starting '&lt;'.
   * @return the token (not {@code null})
   */
  Token get tag => _tag;
  /**
   * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
   * to edit the AST structure.
   * @return the children (not {@code null}, contains no {@code null}s)
   */
  List<XmlTagNode> get tagNodes => _tagNodes;
  void visitChildren(XmlVisitor<Object> visitor) {
    for (XmlAttributeNode node in _attributes) {
      node.accept(visitor);
    }
    for (XmlTagNode node in _tagNodes) {
      node.accept(visitor);
    }
  }
}
/**
 * Instances of the class {@code HtmlParser} are used to parse tokens into a AST structure comprised
 * of {@link XmlNode}s.
 * @coverage dart.engine.html
 */
class HtmlParser extends XmlParser {
  static Set<String> SELF_CLOSING = new Set<String>();
  /**
   * Construct a parser for the specified source.
   * @param source the source being parsed
   */
  HtmlParser(Source source) : super(source) {
  }
  /**
   * Parse the tokens specified by the given scan result.
   * @param scanResult the result of scanning an HTML source (not {@code null})
   * @return the parse result (not {@code null})
   */
  HtmlParseResult parse(HtmlScanResult scanResult) {
    Token firstToken = scanResult.token;
    List<XmlTagNode> tagNodes = parseTopTagNodes(firstToken);
    HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken);
    return new HtmlParseResult(firstToken, scanResult.lineStarts, unit);
  }
  /**
   * Scan then parse the specified source.
   * @param source the source to be scanned and parsed (not {@code null})
   * @return the parse result (not {@code null})
   */
  HtmlParseResult parse2(Source source) {
    HtmlScanner scanner = new HtmlScanner(source);
    source.getContents(scanner);
    return parse(scanner.result);
  }
  bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
}
/**
 * Instances of the class {@code HtmlUnit} represent the contents of an HTML file.
 * @coverage dart.engine.html
 */
class HtmlUnit extends XmlNode {
  /**
   * The first token in the token stream that was parsed to form this HTML unit.
   */
  Token _beginToken;
  /**
   * The last token in the token stream that was parsed to form this compilation unit. This token
   * should always have a type of {@link TokenType.EOF}.
   */
  Token _endToken;
  /**
   * The tag nodes contained in the receiver (not {@code null}, contains no {@code null}s).
   */
  List<XmlTagNode> _tagNodes;
  /**
   * The element associated with this HTML unit or {@code null} if the receiver is not resolved.
   */
  HtmlElementImpl _element;
  /**
   * Construct a new instance representing the content of an HTML file.
   * @param beginToken the first token in the file (not {@code null})
   * @param tagNodes child tag nodes of the receiver (not {@code null}, contains no {@code null}s)
   * @param endToken the last token in the token stream which should be of type{@link TokenType.EOF}
   */
  HtmlUnit(Token beginToken, List<XmlTagNode> tagNodes, Token endToken) {
    this._beginToken = beginToken;
    this._tagNodes = becomeParentOf(tagNodes);
    this._endToken = endToken;
  }
  accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
  Token get beginToken => _beginToken;
  /**
   * Return the element associated with this HTML unit.
   * @return the element or {@code null} if the receiver is not resolved
   */
  HtmlElementImpl get element => _element;
  Token get endToken => _endToken;
  /**
   * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
   * to edit the AST structure.
   * @return the children (not {@code null}, contains no {@code null}s)
   */
  List<XmlTagNode> get tagNodes => _tagNodes;
  /**
   * Set the element associated with this HTML unit.
   * @param element the element
   */
  void set element(HtmlElementImpl element18) {
    this._element = element18;
  }
  void visitChildren(XmlVisitor<Object> visitor) {
    for (XmlTagNode node in _tagNodes) {
      node.accept(visitor);
    }
  }
}