// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:source_span/source_span.dart';
import 'package:string_scanner/string_scanner.dart';

import 'event.dart';
import 'scanner.dart';
import 'style.dart';
import 'token.dart';
import 'utils.dart';
import 'yaml_document.dart';
import 'yaml_exception.dart';

/// A parser that reads [Token]s emitted by a [Scanner] and emits [Event]s.
///
/// This is based on the libyaml parser, available at
/// https://github.com/yaml/libyaml/blob/master/src/parser.c. The license for
/// that is available in ../../libyaml-license.txt.
class Parser {
  /// The underlying [Scanner] that generates [Token]s.
  final Scanner _scanner;

  /// The stack of parse states for nested contexts.
  final _states = List<_State>();

  /// The current parse state.
  var _state = _State.STREAM_START;

  /// The custom tag directives, by tag handle.
  final _tagDirectives = Map<String, TagDirective>();

  /// Whether the parser has finished parsing.
  bool get isDone => _state == _State.END;

  /// Creates a parser that parses [source].
  ///
  /// [sourceUrl] can be a String or a [Uri].
  Parser(String source, {sourceUrl})
      : _scanner = Scanner(source, sourceUrl: sourceUrl);

  /// Consumes and returns the next event.
  Event parse() {
    try {
      if (isDone) throw StateError("No more events.");
      var event = _stateMachine();
      return event;
    } on StringScannerException catch (error) {
      throw YamlException(error.message, error.span);
    }
  }

  /// Dispatches parsing based on the current state.
  Event _stateMachine() {
    switch (_state) {
      case _State.STREAM_START:
        return _parseStreamStart();
      case _State.DOCUMENT_START:
        return _parseDocumentStart();
      case _State.DOCUMENT_CONTENT:
        return _parseDocumentContent();
      case _State.DOCUMENT_END:
        return _parseDocumentEnd();
      case _State.BLOCK_NODE:
        return _parseNode(block: true);
      case _State.BLOCK_NODE_OR_INDENTLESS_SEQUENCE:
        return _parseNode(block: true, indentlessSequence: true);
      case _State.FLOW_NODE:
        return _parseNode();
      case _State.BLOCK_SEQUENCE_FIRST_ENTRY:
        // Scan past the `BLOCK-SEQUENCE-FIRST-ENTRY` token to the
        // `BLOCK-SEQUENCE-ENTRY` token.
        _scanner.scan();
        return _parseBlockSequenceEntry();
      case _State.BLOCK_SEQUENCE_ENTRY:
        return _parseBlockSequenceEntry();
      case _State.INDENTLESS_SEQUENCE_ENTRY:
        return _parseIndentlessSequenceEntry();
      case _State.BLOCK_MAPPING_FIRST_KEY:
        // Scan past the `BLOCK-MAPPING-FIRST-KEY` token to the
        // `BLOCK-MAPPING-KEY` token.
        _scanner.scan();
        return _parseBlockMappingKey();
      case _State.BLOCK_MAPPING_KEY:
        return _parseBlockMappingKey();
      case _State.BLOCK_MAPPING_VALUE:
        return _parseBlockMappingValue();
      case _State.FLOW_SEQUENCE_FIRST_ENTRY:
        return _parseFlowSequenceEntry(first: true);
      case _State.FLOW_SEQUENCE_ENTRY:
        return _parseFlowSequenceEntry();
      case _State.FLOW_SEQUENCE_ENTRY_MAPPING_KEY:
        return _parseFlowSequenceEntryMappingKey();
      case _State.FLOW_SEQUENCE_ENTRY_MAPPING_VALUE:
        return _parseFlowSequenceEntryMappingValue();
      case _State.FLOW_SEQUENCE_ENTRY_MAPPING_END:
        return _parseFlowSequenceEntryMappingEnd();
      case _State.FLOW_MAPPING_FIRST_KEY:
        return _parseFlowMappingKey(first: true);
      case _State.FLOW_MAPPING_KEY:
        return _parseFlowMappingKey();
      case _State.FLOW_MAPPING_VALUE:
        return _parseFlowMappingValue();
      case _State.FLOW_MAPPING_EMPTY_VALUE:
        return _parseFlowMappingValue(empty: true);
      default:
        throw "Unreachable";
    }
  }

  /// Parses the production:
  ///
  ///     stream ::=
  ///       STREAM-START implicit_document? explicit_document* STREAM-END
  ///       ************
  Event _parseStreamStart() {
    var token = _scanner.scan();
    assert(token.type == TokenType.STREAM_START);

    _state = _State.DOCUMENT_START;
    return Event(EventType.STREAM_START, token.span);
  }

  /// Parses the productions:
  ///
  ///     implicit_document    ::= block_node DOCUMENT-END*
  ///                              *
  ///     explicit_document    ::=
  ///       DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
  ///       *************************
  Event _parseDocumentStart() {
    var token = _scanner.peek();

    // libyaml requires any document beyond the first in the stream to have an
    // explicit document start indicator, but the spec allows it to be omitted
    // as long as there was an end indicator.

    // Parse extra document end indicators.
    while (token.type == TokenType.DOCUMENT_END) {
      token = _scanner.advance();
    }

    if (token.type != TokenType.VERSION_DIRECTIVE &&
        token.type != TokenType.TAG_DIRECTIVE &&
        token.type != TokenType.DOCUMENT_START &&
        token.type != TokenType.STREAM_END) {
      // Parse an implicit document.
      _processDirectives();
      _states.add(_State.DOCUMENT_END);
      _state = _State.BLOCK_NODE;
      return DocumentStartEvent(token.span.start.pointSpan());
    }

    if (token.type == TokenType.STREAM_END) {
      _state = _State.END;
      _scanner.scan();
      return Event(EventType.STREAM_END, token.span);
    }

    // Parse an explicit document.
    var start = token.span;
    var pair = _processDirectives();
    var versionDirective = pair.first;
    var tagDirectives = pair.last;
    token = _scanner.peek();
    if (token.type != TokenType.DOCUMENT_START) {
      throw YamlException("Expected document start.", token.span);
    }

    _states.add(_State.DOCUMENT_END);
    _state = _State.DOCUMENT_CONTENT;
    _scanner.scan();
    return DocumentStartEvent(start.expand(token.span),
        versionDirective: versionDirective,
        tagDirectives: tagDirectives,
        isImplicit: false);
  }

  /// Parses the productions:
  ///
  ///     explicit_document    ::=
  ///       DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
  ///                                 ***********
  Event _parseDocumentContent() {
    var token = _scanner.peek();

    switch (token.type) {
      case TokenType.VERSION_DIRECTIVE:
      case TokenType.TAG_DIRECTIVE:
      case TokenType.DOCUMENT_START:
      case TokenType.DOCUMENT_END:
      case TokenType.STREAM_END:
        _state = _states.removeLast();
        return _processEmptyScalar(token.span.start);
      default:
        return _parseNode(block: true);
    }
  }

  /// Parses the productions:
  ///
  ///     implicit_document    ::= block_node DOCUMENT-END*
  ///                                         *************
  ///     explicit_document    ::=
  ///       DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
  ///                                             *************
  Event _parseDocumentEnd() {
    _tagDirectives.clear();
    _state = _State.DOCUMENT_START;

    var token = _scanner.peek();
    if (token.type == TokenType.DOCUMENT_END) {
      _scanner.scan();
      return DocumentEndEvent(token.span, isImplicit: false);
    } else {
      return DocumentEndEvent(token.span.start.pointSpan(), isImplicit: true);
    }
  }

  /// Parses the productions:
  ///
  ///     block_node_or_indentless_sequence    ::=
  ///       ALIAS
  ///       *****
  ///       | properties (block_content | indentless_block_sequence)?
  ///         **********  *
  ///       | block_content | indentless_block_sequence
  ///         *
  ///     block_node           ::= ALIAS
  ///                              *****
  ///                              | properties block_content?
  ///                                ********** *
  ///                              | block_content
  ///                                *
  ///     flow_node            ::= ALIAS
  ///                              *****
  ///                              | properties flow_content?
  ///                                ********** *
  ///                              | flow_content
  ///                                *
  ///     properties           ::= TAG ANCHOR? | ANCHOR TAG?
  ///                              *************************
  ///     block_content        ::= block_collection | flow_collection | SCALAR
  ///                                                                   ******
  ///     flow_content         ::= flow_collection | SCALAR
  ///                                                ******
  Event _parseNode({bool block = false, bool indentlessSequence = false}) {
    var token = _scanner.peek();

    if (token is AliasToken) {
      _scanner.scan();
      _state = _states.removeLast();
      return AliasEvent(token.span, token.name);
    }

    String anchor;
    TagToken tagToken;
    var span = token.span.start.pointSpan();
    Token parseAnchor(AnchorToken token) {
      anchor = token.name;
      span = span.expand(token.span);
      return _scanner.advance();
    }

    Token parseTag(TagToken token) {
      tagToken = token;
      span = span.expand(token.span);
      return _scanner.advance();
    }

    if (token is AnchorToken) {
      token = parseAnchor(token as AnchorToken);
      if (token is TagToken) token = parseTag(token as TagToken);
    } else if (token is TagToken) {
      token = parseTag(token as TagToken);
      if (token is AnchorToken) token = parseAnchor(token as AnchorToken);
    }

    String tag;
    if (tagToken != null) {
      if (tagToken.handle == null) {
        tag = tagToken.suffix;
      } else {
        var tagDirective = _tagDirectives[tagToken.handle];
        if (tagDirective == null) {
          throw YamlException("Undefined tag handle.", tagToken.span);
        }

        tag = tagDirective.prefix + tagToken.suffix;
      }
    }

    if (indentlessSequence && token.type == TokenType.BLOCK_ENTRY) {
      _state = _State.INDENTLESS_SEQUENCE_ENTRY;
      return SequenceStartEvent(span.expand(token.span), CollectionStyle.BLOCK,
          anchor: anchor, tag: tag);
    }

    if (token is ScalarToken) {
      // All non-plain scalars have the "!" tag by default.
      if (tag == null && token.style != ScalarStyle.PLAIN) tag = "!";

      _state = _states.removeLast();
      _scanner.scan();
      return ScalarEvent(span.expand(token.span), token.value, token.style,
          anchor: anchor, tag: tag);
    }

    if (token.type == TokenType.FLOW_SEQUENCE_START) {
      _state = _State.FLOW_SEQUENCE_FIRST_ENTRY;
      return SequenceStartEvent(span.expand(token.span), CollectionStyle.FLOW,
          anchor: anchor, tag: tag);
    }

    if (token.type == TokenType.FLOW_MAPPING_START) {
      _state = _State.FLOW_MAPPING_FIRST_KEY;
      return MappingStartEvent(span.expand(token.span), CollectionStyle.FLOW,
          anchor: anchor, tag: tag);
    }

    if (block && token.type == TokenType.BLOCK_SEQUENCE_START) {
      _state = _State.BLOCK_SEQUENCE_FIRST_ENTRY;
      return SequenceStartEvent(span.expand(token.span), CollectionStyle.BLOCK,
          anchor: anchor, tag: tag);
    }

    if (block && token.type == TokenType.BLOCK_MAPPING_START) {
      _state = _State.BLOCK_MAPPING_FIRST_KEY;
      return MappingStartEvent(span.expand(token.span), CollectionStyle.BLOCK,
          anchor: anchor, tag: tag);
    }

    if (anchor != null || tag != null) {
      _state = _states.removeLast();
      return ScalarEvent(span, '', ScalarStyle.PLAIN, anchor: anchor, tag: tag);
    }

    throw YamlException("Expected node content.", span);
  }

  /// Parses the productions:
  ///
  ///     block_sequence ::=
  ///       BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
  ///       ********************  *********** *             *********
  Event _parseBlockSequenceEntry() {
    var token = _scanner.peek();

    if (token.type == TokenType.BLOCK_ENTRY) {
      token = _scanner.advance();

      if (token.type == TokenType.BLOCK_ENTRY ||
          token.type == TokenType.BLOCK_END) {
        _state = _State.BLOCK_SEQUENCE_ENTRY;
        return _processEmptyScalar(token.span.end);
      } else {
        _states.add(_State.BLOCK_SEQUENCE_ENTRY);
        return _parseNode(block: true);
      }
    }

    if (token.type == TokenType.BLOCK_END) {
      _scanner.scan();
      _state = _states.removeLast();
      return Event(EventType.SEQUENCE_END, token.span);
    }

    throw YamlException("While parsing a block collection, expected '-'.",
        token.span.start.pointSpan());
  }

  /// Parses the productions:
  ///
  ///     indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
  ///                               *********** *
  Event _parseIndentlessSequenceEntry() {
    var token = _scanner.peek();

    if (token.type != TokenType.BLOCK_ENTRY) {
      _state = _states.removeLast();
      return Event(EventType.SEQUENCE_END, token.span.start.pointSpan());
    }

    var start = token.span.start;
    token = _scanner.advance();

    if (token.type == TokenType.BLOCK_ENTRY ||
        token.type == TokenType.KEY ||
        token.type == TokenType.VALUE ||
        token.type == TokenType.BLOCK_END) {
      _state = _State.INDENTLESS_SEQUENCE_ENTRY;
      return _processEmptyScalar(start);
    } else {
      _states.add(_State.INDENTLESS_SEQUENCE_ENTRY);
      return _parseNode(block: true);
    }
  }

  /// Parses the productions:
  ///
  ///     block_mapping        ::= BLOCK-MAPPING_START
  ///                              *******************
  ///                              ((KEY block_node_or_indentless_sequence?)?
  ///                                *** *
  ///                              (VALUE block_node_or_indentless_sequence?)?)*
  ///
  ///                              BLOCK-END
  ///                              *********
  Event _parseBlockMappingKey() {
    var token = _scanner.peek();
    if (token.type == TokenType.KEY) {
      var start = token.span.start;
      token = _scanner.advance();

      if (token.type == TokenType.KEY ||
          token.type == TokenType.VALUE ||
          token.type == TokenType.BLOCK_END) {
        _state = _State.BLOCK_MAPPING_VALUE;
        return _processEmptyScalar(start);
      } else {
        _states.add(_State.BLOCK_MAPPING_VALUE);
        return _parseNode(block: true, indentlessSequence: true);
      }
    }

    // libyaml doesn't allow empty keys without an explicit key indicator, but
    // the spec does. See example 8.18:
    // http://yaml.org/spec/1.2/spec.html#id2798896.
    if (token.type == TokenType.VALUE) {
      _state = _State.BLOCK_MAPPING_VALUE;
      return _processEmptyScalar(token.span.start);
    }

    if (token.type == TokenType.BLOCK_END) {
      _scanner.scan();
      _state = _states.removeLast();
      return Event(EventType.MAPPING_END, token.span);
    }

    throw YamlException("Expected a key while parsing a block mapping.",
        token.span.start.pointSpan());
  }

  /// Parses the productions:
  ///
  ///     block_mapping        ::= BLOCK-MAPPING_START
  ///
  ///                              ((KEY block_node_or_indentless_sequence?)?
  ///
  ///                              (VALUE block_node_or_indentless_sequence?)?)*
  ///                               ***** *
  ///                              BLOCK-END
  ///
  Event _parseBlockMappingValue() {
    var token = _scanner.peek();

    if (token.type != TokenType.VALUE) {
      _state = _State.BLOCK_MAPPING_KEY;
      return _processEmptyScalar(token.span.start);
    }

    var start = token.span.start;
    token = _scanner.advance();
    if (token.type == TokenType.KEY ||
        token.type == TokenType.VALUE ||
        token.type == TokenType.BLOCK_END) {
      _state = _State.BLOCK_MAPPING_KEY;
      return _processEmptyScalar(start);
    } else {
      _states.add(_State.BLOCK_MAPPING_KEY);
      return _parseNode(block: true, indentlessSequence: true);
    }
  }

  /// Parses the productions:
  ///
  ///     flow_sequence        ::= FLOW-SEQUENCE-START
  ///                              *******************
  ///                              (flow_sequence_entry FLOW-ENTRY)*
  ///                               *                   **********
  ///                              flow_sequence_entry?
  ///                              *
  ///                              FLOW-SEQUENCE-END
  ///                              *****************
  ///     flow_sequence_entry  ::=
  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
  ///       *
  Event _parseFlowSequenceEntry({bool first = false}) {
    if (first) _scanner.scan();
    var token = _scanner.peek();

    if (token.type != TokenType.FLOW_SEQUENCE_END) {
      if (!first) {
        if (token.type != TokenType.FLOW_ENTRY) {
          throw YamlException(
              "While parsing a flow sequence, expected ',' or ']'.",
              token.span.start.pointSpan());
        }

        token = _scanner.advance();
      }

      if (token.type == TokenType.KEY) {
        _state = _State.FLOW_SEQUENCE_ENTRY_MAPPING_KEY;
        _scanner.scan();
        return MappingStartEvent(token.span, CollectionStyle.FLOW);
      } else if (token.type != TokenType.FLOW_SEQUENCE_END) {
        _states.add(_State.FLOW_SEQUENCE_ENTRY);
        return _parseNode();
      }
    }

    _scanner.scan();
    _state = _states.removeLast();
    return Event(EventType.SEQUENCE_END, token.span);
  }

  /// Parses the productions:
  ///
  ///     flow_sequence_entry  ::=
  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
  ///                   *** *
  Event _parseFlowSequenceEntryMappingKey() {
    var token = _scanner.peek();

    if (token.type == TokenType.VALUE ||
        token.type == TokenType.FLOW_ENTRY ||
        token.type == TokenType.FLOW_SEQUENCE_END) {
      // libyaml consumes the token here, but that seems like a bug, since it
      // always causes [_parseFlowSequenceEntryMappingValue] to emit an empty
      // scalar.

      var start = token.span.start;
      _state = _State.FLOW_SEQUENCE_ENTRY_MAPPING_VALUE;
      return _processEmptyScalar(start);
    } else {
      _states.add(_State.FLOW_SEQUENCE_ENTRY_MAPPING_VALUE);
      return _parseNode();
    }
  }

  /// Parses the productions:
  ///
  ///     flow_sequence_entry  ::=
  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
  ///                                   ***** *
  Event _parseFlowSequenceEntryMappingValue() {
    var token = _scanner.peek();

    if (token.type == TokenType.VALUE) {
      token = _scanner.advance();
      if (token.type != TokenType.FLOW_ENTRY &&
          token.type != TokenType.FLOW_SEQUENCE_END) {
        _states.add(_State.FLOW_SEQUENCE_ENTRY_MAPPING_END);
        return _parseNode();
      }
    }

    _state = _State.FLOW_SEQUENCE_ENTRY_MAPPING_END;
    return _processEmptyScalar(token.span.start);
  }

  /// Parses the productions:
  ///
  ///     flow_sequence_entry  ::=
  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
  ///                                                   *
  Event _parseFlowSequenceEntryMappingEnd() {
    _state = _State.FLOW_SEQUENCE_ENTRY;
    return Event(EventType.MAPPING_END, _scanner.peek().span.start.pointSpan());
  }

  /// Parses the productions:
  ///
  ///     flow_mapping         ::= FLOW-MAPPING-START
  ///                              ******************
  ///                              (flow_mapping_entry FLOW-ENTRY)*
  ///                               *                  **********
  ///                              flow_mapping_entry?
  ///                              ******************
  ///                              FLOW-MAPPING-END
  ///                              ****************
  ///     flow_mapping_entry   ::=
  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
  ///       *           *** *
  Event _parseFlowMappingKey({bool first = false}) {
    if (first) _scanner.scan();
    var token = _scanner.peek();

    if (token.type != TokenType.FLOW_MAPPING_END) {
      if (!first) {
        if (token.type != TokenType.FLOW_ENTRY) {
          throw YamlException(
              "While parsing a flow mapping, expected ',' or '}'.",
              token.span.start.pointSpan());
        }

        token = _scanner.advance();
      }

      if (token.type == TokenType.KEY) {
        token = _scanner.advance();
        if (token.type != TokenType.VALUE &&
            token.type != TokenType.FLOW_ENTRY &&
            token.type != TokenType.FLOW_MAPPING_END) {
          _states.add(_State.FLOW_MAPPING_VALUE);
          return _parseNode();
        } else {
          _state = _State.FLOW_MAPPING_VALUE;
          return _processEmptyScalar(token.span.start);
        }
      } else if (token.type != TokenType.FLOW_MAPPING_END) {
        _states.add(_State.FLOW_MAPPING_EMPTY_VALUE);
        return _parseNode();
      }
    }

    _scanner.scan();
    _state = _states.removeLast();
    return Event(EventType.MAPPING_END, token.span);
  }

  /// Parses the productions:
  ///
  ///     flow_mapping_entry   ::=
  ///       flow_node | KEY flow_node? (VALUE flow_node?)?
  ///                *                  ***** *
  Event _parseFlowMappingValue({bool empty = false}) {
    var token = _scanner.peek();

    if (empty) {
      _state = _State.FLOW_MAPPING_KEY;
      return _processEmptyScalar(token.span.start);
    }

    if (token.type == TokenType.VALUE) {
      token = _scanner.advance();
      if (token.type != TokenType.FLOW_ENTRY &&
          token.type != TokenType.FLOW_MAPPING_END) {
        _states.add(_State.FLOW_MAPPING_KEY);
        return _parseNode();
      }
    }

    _state = _State.FLOW_MAPPING_KEY;
    return _processEmptyScalar(token.span.start);
  }

  /// Generate an empty scalar event.
  Event _processEmptyScalar(SourceLocation location) =>
      ScalarEvent(location.pointSpan() as FileSpan, '', ScalarStyle.PLAIN);

  /// Parses directives.
  Pair<VersionDirective, List<TagDirective>> _processDirectives() {
    var token = _scanner.peek();

    VersionDirective versionDirective;
    var tagDirectives = <TagDirective>[];
    while (token.type == TokenType.VERSION_DIRECTIVE ||
        token.type == TokenType.TAG_DIRECTIVE) {
      if (token is VersionDirectiveToken) {
        if (versionDirective != null) {
          throw YamlException("Duplicate %YAML directive.", token.span);
        }

        if (token.major != 1 || token.minor == 0) {
          throw YamlException(
              "Incompatible YAML document. This parser only supports YAML 1.1 "
              "and 1.2.",
              token.span);
        } else if (token.minor > 2) {
          // TODO(nweiz): Print to stderr when issue 6943 is fixed and dart:io
          // is available.
          warn("Warning: this parser only supports YAML 1.1 and 1.2.",
              token.span);
        }

        versionDirective = VersionDirective(token.major, token.minor);
      } else if (token is TagDirectiveToken) {
        var tagDirective = TagDirective(token.handle, token.prefix);
        _appendTagDirective(tagDirective, token.span);
        tagDirectives.add(tagDirective);
      }

      token = _scanner.advance();
    }

    _appendTagDirective(TagDirective("!", "!"), token.span.start.pointSpan(),
        allowDuplicates: true);
    _appendTagDirective(
        TagDirective("!!", "tag:yaml.org,2002:"), token.span.start.pointSpan(),
        allowDuplicates: true);

    return Pair(versionDirective, tagDirectives);
  }

  /// Adds a tag directive to the directives stack.
  void _appendTagDirective(TagDirective newDirective, FileSpan span,
      {bool allowDuplicates = false}) {
    if (_tagDirectives.containsKey(newDirective.handle)) {
      if (allowDuplicates) return;
      throw YamlException("Duplicate %TAG directive.", span);
    }

    _tagDirectives[newDirective.handle] = newDirective;
  }
}

/// The possible states for the parser.
class _State {
  /// Expect [TokenType.STREAM_START].
  static const STREAM_START = _State("STREAM_START");

  /// Expect the beginning of an implicit document.
  static const IMPLICIT_DOCUMENT_START = _State("IMPLICIT_DOCUMENT_START");

  /// Expect [TokenType.DOCUMENT_START].
  static const DOCUMENT_START = _State("DOCUMENT_START");

  /// Expect the content of a document.
  static const DOCUMENT_CONTENT = _State("DOCUMENT_CONTENT");

  /// Expect [TokenType.DOCUMENT_END].
  static const DOCUMENT_END = _State("DOCUMENT_END");

  /// Expect a block node.
  static const BLOCK_NODE = _State("BLOCK_NODE");

  /// Expect a block node or indentless sequence.
  static const BLOCK_NODE_OR_INDENTLESS_SEQUENCE =
      _State("BLOCK_NODE_OR_INDENTLESS_SEQUENCE");

  /// Expect a flow node.
  static const FLOW_NODE = _State("FLOW_NODE");

  /// Expect the first entry of a block sequence.
  static const BLOCK_SEQUENCE_FIRST_ENTRY =
      _State("BLOCK_SEQUENCE_FIRST_ENTRY");

  /// Expect an entry of a block sequence.
  static const BLOCK_SEQUENCE_ENTRY = _State("BLOCK_SEQUENCE_ENTRY");

  /// Expect an entry of an indentless sequence.
  static const INDENTLESS_SEQUENCE_ENTRY = _State("INDENTLESS_SEQUENCE_ENTRY");

  /// Expect the first key of a block mapping.
  static const BLOCK_MAPPING_FIRST_KEY = _State("BLOCK_MAPPING_FIRST_KEY");

  /// Expect a block mapping key.
  static const BLOCK_MAPPING_KEY = _State("BLOCK_MAPPING_KEY");

  /// Expect a block mapping value.
  static const BLOCK_MAPPING_VALUE = _State("BLOCK_MAPPING_VALUE");

  /// Expect the first entry of a flow sequence.
  static const FLOW_SEQUENCE_FIRST_ENTRY = _State("FLOW_SEQUENCE_FIRST_ENTRY");

  /// Expect an entry of a flow sequence.
  static const FLOW_SEQUENCE_ENTRY = _State("FLOW_SEQUENCE_ENTRY");

  /// Expect a key of an ordered mapping.
  static const FLOW_SEQUENCE_ENTRY_MAPPING_KEY =
      _State("FLOW_SEQUENCE_ENTRY_MAPPING_KEY");

  /// Expect a value of an ordered mapping.
  static const FLOW_SEQUENCE_ENTRY_MAPPING_VALUE =
      _State("FLOW_SEQUENCE_ENTRY_MAPPING_VALUE");

  /// Expect the and of an ordered mapping entry.
  static const FLOW_SEQUENCE_ENTRY_MAPPING_END =
      _State("FLOW_SEQUENCE_ENTRY_MAPPING_END");

  /// Expect the first key of a flow mapping.
  static const FLOW_MAPPING_FIRST_KEY = _State("FLOW_MAPPING_FIRST_KEY");

  /// Expect a key of a flow mapping.
  static const FLOW_MAPPING_KEY = _State("FLOW_MAPPING_KEY");

  /// Expect a value of a flow mapping.
  static const FLOW_MAPPING_VALUE = _State("FLOW_MAPPING_VALUE");

  /// Expect an empty value of a flow mapping.
  static const FLOW_MAPPING_EMPTY_VALUE = _State("FLOW_MAPPING_EMPTY_VALUE");

  /// Expect nothing.
  static const END = _State("END");

  final String name;

  const _State(this.name);

  String toString() => name;
}
