// Copyright (c) 2021, 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 '../ast.dart';
import 'coverage.dart';

Map<T, int> _createPending<T>(
  Iterable<T> kinds, [
  Set<T> experimentalKinds = const {},
]) {
  return <T, int>{
    for (T kind in kinds)
      if (!experimentalKinds.contains(kind)) kind: 0,
  };
}

/// Helper class used to generate ASTs that contain all different nodes.
class NodeCreator {
  final Uri _uri;

  /// File offset counter.
  ///
  /// Used to generate distinct file offsets through [_needFileOffset].
  int _fileOffset = 0;

  /// The parent [Component] for all created libraries, classes, extensions,
  /// typedefs and members.
  final Component _component = new Component();

  /// These fields contain maps of requested nodes different kinds that are
  /// still pending. The mapped values are used to track how many nodes of the
  /// specific kind have been created. When all variants of a kind have been
  /// created, the entry is removed from the map.
  final Map<ExpressionKind, int> _pendingExpressions;
  final Map<StatementKind, int> _pendingStatements;
  final Map<DartTypeKind, int> _pendingDartTypes;
  final Map<ConstantKind, int> _pendingConstants;
  final Map<PatternKind, int> _pendingPatterns;
  final Map<InitializerKind, int> _pendingInitializers;
  final Map<MemberKind, int> _pendingMembers;
  final Map<NodeKind, int> _pendingNodes;
  final Map<VariableKind, int> _pendingVariables;

  /// The set of all kinds of nodes created by this node creator.
  final Set<Object> _createdKinds = {};

  /// These fields contain list of nodes needed for the creation of other nodes.
  ///
  /// Needed nodes are nodes that need to exist prior to the node that required
  /// it. For instance, to create an [InterfaceType] node, a [Class] node must
  /// exist for the [InterfaceType] to reference.
  ///
  /// Needed nodes are added to the context of the created nodes. For instance,
  /// a needed [Class] is added to the [_component] and a needed
  /// [Variable] is added to a enclosing [Block].
  List<Library> _neededLibraries = [];
  List<Class> _neededClasses = [];
  List<ExtensionTypeDeclaration> _neededExtensionTypeDeclarations = [];
  List<Typedef> _neededTypedefs = [];
  List<TypeParameter> _neededTypeParameters = [];
  List<StructuralParameter> _neededStructuralParameters = [];
  List<Constructor> _neededConstructors = [];
  List<Procedure> _neededRedirectingFactories = [];
  List<Procedure> _neededProcedures = [];
  List<Field> _neededFields = [];
  List<LibraryDependency> _neededLibraryDependencies = [];
  List<DeclaredVariable> _neededVariables = [];
  List<LabeledStatement> _neededLabeledStatements = [];
  List<FunctionDeclaration> _neededFunctionDeclarations = [];
  List<SwitchCase> _neededSwitchCases = [];

  /// Creates a [NodeCreator] requested to create nodes of the specified kinds.
  new({
    Iterable<ExpressionKind> expressions = ExpressionKind.values,
    Iterable<StatementKind> statements = StatementKind.values,
    Iterable<DartTypeKind> dartTypes = DartTypeKind.values,
    Iterable<ConstantKind> constants = ConstantKind.values,
    Iterable<PatternKind> patterns = PatternKind.values,
    Iterable<InitializerKind> initializers = InitializerKind.values,
    Iterable<MemberKind> members = MemberKind.values,
    Iterable<VariableKind> variables = VariableKind.values,
    Iterable<NodeKind> nodes = NodeKind.values,
  }) : _pendingExpressions = _createPending<ExpressionKind>(expressions, {}),
       _pendingStatements = _createPending<StatementKind>(statements),
       _pendingDartTypes = _createPending<DartTypeKind>(dartTypes, {
         DartTypeKind.FunctionTypeParameterType,
         DartTypeKind.ClassTypeParameterType,
       }),
       _pendingConstants = _createPending<ConstantKind>(constants),
       _pendingPatterns = _createPending<PatternKind>(patterns),
       _pendingInitializers = _createPending<InitializerKind>(initializers),
       _pendingMembers = _createPending<MemberKind>(members),
       _pendingVariables = _createPending<VariableKind>(variables),
       _pendingNodes = _createPending<NodeKind>(nodes, {NodeKind.TypeVariable}),
       _uri = Uri.parse('test:uri') {
    _createdKinds.addAll(_pendingExpressions.keys);
    _createdKinds.addAll(_pendingStatements.keys);
    _createdKinds.addAll(_pendingDartTypes.keys);
    _createdKinds.addAll(_pendingInitializers.keys);
    _createdKinds.addAll(_pendingMembers.keys);
    _createdKinds.addAll(_pendingVariables.keys);
    _createdKinds.addAll(_pendingNodes.keys);
  }

  /// The kinds created by this node creator.
  Iterable<Object> get createdKinds => _createdKinds;

  /// Wraps [statement] in nodes needed in the statement context.
  ///
  /// For instance, if a [LabeledStatement] was needed for the creation of
  /// [statement], [statement] is wrapped inside the labeled statement.
  Statement _ensureContext(Statement statement) {
    if (_neededSwitchCases.isNotEmpty) {
      statement = SwitchStatement(NullLiteral(), [
        ..._neededSwitchCases,
        SwitchCase([NullLiteral()], [TreeNode.noOffset], Block([statement])),
      ]);
    }
    _neededSwitchCases.clear();
    for (LabeledStatement labeledStatement in _neededLabeledStatements) {
      labeledStatement.body = statement;
      statement = labeledStatement;
    }
    _neededLabeledStatements.clear();
    statement = Block([
      for (DeclaredVariable neededVariable in _neededVariables)
        VariableStatement(VariableDeclaration(neededVariable)),
      ..._neededFunctionDeclarations,
      statement,
    ]);
    _neededFunctionDeclarations.clear();
    _neededVariables.clear();
    return statement;
  }

  /// Adds [statement] to [statements] including any nodes needed in the
  /// context.
  void _addStatement(List<Statement> statements, Statement statement) {
    statements.add(_ensureContext(statement));
  }

  /// Adds [expression] to [statements] including any nodes needed in the
  /// context.
  void _addExpression(List<Statement> statements, Expression expression) {
    _addStatement(statements, ExpressionStatement(expression));
  }

  /// Adds [type] to [statements] including any nodes needed in the context.
  void _addDartType(List<Statement> statements, DartType type) {
    _addExpression(statements, TypeLiteral(type));
  }

  /// Adds [constant] to [statements] including any nodes needed in the context.
  void _addConstant(List<Statement> statements, Constant constant) {
    _addExpression(statements, ConstantExpression(constant));
  }

  /// Adds [pattern] to [statements] including any nodes needed in the context.
  void _addPattern(List<Statement> statements, Pattern pattern) {
    _addExpression(statements, PatternAssignment(pattern, NullLiteral()));
  }

  /// Generates a list of [Statement] containing all pending in-body nodes.
  List<Statement> _generateBodies() {
    List<Statement> statements = [];
    while (_pendingStatements.isNotEmpty) {
      _addStatement(statements, _createStatement());
    }
    while (_pendingExpressions.isNotEmpty) {
      _addExpression(statements, _createExpression());
    }
    while (_pendingDartTypes.isNotEmpty) {
      _addDartType(statements, _createDartType());
    }
    while (_pendingConstants.isNotEmpty) {
      _addConstant(statements, _createConstant());
    }
    while (_pendingVariables.isNotEmpty) {
      Variable variable = _createVariableFromKind(_pendingVariables.keys.first);
      switch (variable) {
        case DeclaredVariable():
          _addStatement(
            statements,
            VariableStatement(VariableDeclaration(variable)),
          );
        case CatchVariable():
          _addStatement(
            statements,
            TryCatch(Block([]), [Catch(variable, Block([]))]),
          );
        case ThisVariable():
          _addExpression(
            statements,
            FunctionExpression(FunctionNode(null, thisVariable: variable)),
          );
        case PositionalParameter():
          _addExpression(
            statements,
            FunctionExpression(
              FunctionNode(null, positionalParameters: [variable]),
            ),
          );
        case NamedParameter():
          _addExpression(
            statements,
            FunctionExpression(FunctionNode(null, namedParameters: [variable])),
          );
      }
    }
    for (NodeKind kind in inBodyNodeKinds) {
      while (_pendingNodes.containsKey(kind)) {
        Node node = _createNodeFromKind(kind);
        switch (kind) {
          case NodeKind.Name:
            _addExpression(
              statements,
              DynamicGet(
                DynamicAccessKind.Dynamic,
                _createExpression(),
                node as Name,
              ),
            );
            break;
          case NodeKind.Arguments:
            _addExpression(
              statements,
              DynamicInvocation(
                DynamicAccessKind.Dynamic,
                _createExpression(),
                _createName(),
                node as Arguments,
              ),
            );
            break;
          case NodeKind.Catch:
            _addStatement(
              statements,
              TryCatch(_createStatement(), [node as Catch]),
            );
            break;
          case NodeKind.FunctionNode:
            _addExpression(
              statements,
              FunctionExpression(node as FunctionNode),
            );
            break;
          case NodeKind.MapLiteralEntry:
            _addExpression(statements, MapLiteral([node as MapLiteralEntry]));
            break;
          case NodeKind.MapPatternEntry:
            _addPattern(
              statements,
              MapPattern(null, null, [node as MapPatternEntry]),
            );
            break;
          case NodeKind.MapPatternRestEntry:
            _addPattern(
              statements,
              MapPattern(null, null, [node as MapPatternRestEntry]),
            );
            break;
          case NodeKind.NamedExpression:
            _addExpression(
              statements,
              DynamicInvocation(
                DynamicAccessKind.Dynamic,
                _createExpression(),
                _createName(),
                Arguments([], named: [node as NamedExpression]),
              ),
            );
            break;
          case NodeKind.NamedType:
            _addDartType(
              statements,
              FunctionType(
                [],
                _createDartType(),
                Nullability.nonNullable,
                namedParameters: [node as NamedType],
              ),
            );
            break;
          case NodeKind.PatternSwitchCase:
            _addStatement(
              statements,
              PatternSwitchStatement(_createExpression(), [
                node as PatternSwitchCase,
              ]),
            );
            break;
          case NodeKind.SwitchCase:
            _addStatement(
              statements,
              SwitchStatement(_createExpression(), [node as SwitchCase]),
            );
            break;
          case NodeKind.SwitchExpressionCase:
            _addExpression(
              statements,
              SwitchExpression(_createExpression(), [
                node as SwitchExpressionCase,
              ]),
            );
            break;
          case NodeKind.NominalParameter:
            _addExpression(
              statements,
              FunctionExpression(
                FunctionNode(
                  Block([]),
                  typeParameters: [node as TypeParameter],
                ),
              ),
            );
            break;
          case NodeKind.VariableDeclaration:
            _addStatement(
              statements,
              VariableStatement(node as VariableDeclaration),
            );
            break;
          default:
            throw new UnimplementedError('Unhandled in body node $kind.');
        }
      }
    }
    return statements;
  }

  /// Generates [Statement]s containing occurrences of all requested nodes.
  List<Statement> generateBodies() {
    List<Statement> statements = _generateBodies();
    Set<Object> unsupportedKinds = {};
    if (_pendingInitializers.isNotEmpty) {
      unsupportedKinds.addAll(_pendingInitializers.keys);
    }
    if (_pendingMembers.isNotEmpty) {
      unsupportedKinds.addAll(_pendingMembers.keys);
    }
    if (_pendingNodes.isNotEmpty) {
      assert(
        _pendingNodes.keys.every((kind) => !inBodyNodeKinds.contains(kind)),
      );
      unsupportedKinds.addAll(_pendingNodes.keys);
    }
    if (unsupportedKinds.isNotEmpty) {
      throw new UnsupportedError(
        'Cannot create these node in a body context: '
        '${unsupportedKinds.join(', ')}',
      );
    }
    return statements;
  }

  /// Generates a [Component] containing occurrences of all requested and needed
  /// nodes.
  Component generateComponent() {
    Class cls = _needClass();
    for (Statement statement in _generateBodies()) {
      cls.addProcedure(
        Procedure(
          _createName(),
          ProcedureKind.Method,
          FunctionNode(statement),
          fileUri: _uri,
        ),
      );
    }
    while (_pendingInitializers.isNotEmpty) {
      Initializer initializer = _createInitializer();
      cls.addConstructor(
        Constructor(
          FunctionNode(null),
          name: _createName(),
          fileUri: _uri,
          initializers: [initializer],
        ),
      );
    }
    while (_pendingMembers.isNotEmpty) {
      Member member = _createMember();
      if (member is Procedure) {
        cls.addProcedure(member);
      } else if (member is Field) {
        cls.addField(member);
      } else if (member is Constructor) {
        cls.addConstructor(member);
      } else {
        throw new UnsupportedError(
          'Unexpected member $member (${member.runtimeType})',
        );
      }
    }
    while (_pendingNodes.isNotEmpty) {
      NodeKind kind = _pendingNodes.keys.first;
      Node node = _createNodeFromKind(kind);
      switch (kind) {
        case NodeKind.Name:
        case NodeKind.Arguments:
        case NodeKind.Catch:
        case NodeKind.FunctionNode:
        case NodeKind.MapLiteralEntry:
        case NodeKind.NamedExpression:
        case NodeKind.NamedType:
        case NodeKind.SwitchCase:
        case NodeKind.NominalParameter:
        case NodeKind.StructuralParameter:
        case NodeKind.MapPatternEntry:
        case NodeKind.MapPatternRestEntry:
        case NodeKind.PatternGuard:
        case NodeKind.PatternSwitchCase:
        case NodeKind.SwitchExpressionCase:
        case NodeKind.TypeVariable:
        case NodeKind.VariableDeclaration:
          throw new UnimplementedError('Expected in body node $kind.');
        case NodeKind.Class:
          _needLibrary().addClass(node as Class);
          break;
        case NodeKind.Combinator:
          _needLibrary().addDependency(
            LibraryDependency.import(
              _needLibrary(),
              combinators: [node as Combinator],
            ),
          );
          break;
        case NodeKind.Component:
          assert(
            identical(node, _component),
            "Cannot create multiple Component nodes.",
          );
          break;
        case NodeKind.Extension:
          _needLibrary().addExtension(node as Extension);
          break;
        case NodeKind.Library:
          _component.libraries.add(node as Library);
          break;
        case NodeKind.LibraryDependency:
          _needLibrary().addDependency(node as LibraryDependency);
          break;
        case NodeKind.LibraryPart:
          _needLibrary().addPart(node as LibraryPart);
          break;
        case NodeKind.Supertype:
          _needLibrary().addClass(
            Class(name: 'foo', fileUri: _uri, supertype: node as Supertype),
          );
          break;
        case NodeKind.Typedef:
          _needLibrary().addTypedef(node as Typedef);
          break;
        case NodeKind.ExtensionTypeDeclaration:
          _needLibrary().addExtensionTypeDeclaration(
            node as ExtensionTypeDeclaration,
          );
          break;
      }
    }
    return _component;
  }

  /// Returns a [Library] node that fits the requirements.
  ///
  /// If no such [Library] exists in [_neededLibraries], a new [Library] is
  /// created and added to [_neededLibraries].
  // TODO(johnniwinther): Add requirements when/where needed.
  Library _needLibrary() {
    for (Library library in _neededLibraries) {
      return library;
    }
    Library library = Library(_uri, fileUri: _uri);
    _neededLibraries.add(library);
    _component.libraries.add(library);
    return library;
  }

  /// Returns a [LibraryDependency] node that fits the requirements.
  ///
  /// If no such [LibraryDependency] exists in [_neededLibraryDependencies], a
  /// new [LibraryDependency] is created and added to
  /// [_neededLibraryDependencies].
  LibraryDependency _needLibraryDependency({bool deferred = false}) {
    for (LibraryDependency libraryDependency in _neededLibraryDependencies) {
      if (!deferred || libraryDependency.isDeferred) {
        return libraryDependency;
      }
    }
    LibraryDependency libraryDependency = deferred
        ? LibraryDependency.deferredImport(_needLibrary(), 'foo')
        : LibraryDependency.import(_needLibrary());
    _neededLibraryDependencies.add(libraryDependency);
    return libraryDependency;
  }

  /// Returns a [Class] node that fits the requirements.
  ///
  /// If no such [Class] exists in [_neededClasses], a new [Class] is
  /// created and added to [_neededClasses].
  // TODO(johnniwinther): Add requirements when/where needed.
  Class _needClass() {
    for (Class cls in _neededClasses) {
      return cls;
    }
    Class cls = Class(name: 'Foo', fileUri: _uri);
    _neededClasses.add(cls);
    _needLibrary().addClass(cls);
    return cls;
  }

  /// Returns an [ExtensionTypeDeclaration] node that fits the requirements.
  ///
  /// If no such [ExtensionTypeDeclaration] exists in
  /// [_neededExtensionTypeDeclarations], a new [ExtensionTypeDeclaration] is
  /// created and added to [_neededExtensionTypeDeclarations].
  // TODO(johnniwinther): Add requirements when/where needed.
  ExtensionTypeDeclaration _needExtensionTypeDeclaration() {
    for (ExtensionTypeDeclaration extensionTypeDeclaration
        in _neededExtensionTypeDeclarations) {
      return extensionTypeDeclaration;
    }
    ExtensionTypeDeclaration extensionTypeDeclaration =
        ExtensionTypeDeclaration(
          name: 'foo',
          fileUri: _uri,
          declaredRepresentationType: const DynamicType(),
        );
    _neededExtensionTypeDeclarations.add(extensionTypeDeclaration);
    _needLibrary().addExtensionTypeDeclaration(extensionTypeDeclaration);
    return extensionTypeDeclaration;
  }

  /// Returns a [Typedef] node that fits the requirements.
  ///
  /// If no such [Typedef] exists in [_neededTypedefs], a new [Typedef] is
  /// created and added to [_neededTypedefs].
  // TODO(johnniwinther): Add requirements when/where needed.
  Typedef _needTypedef() {
    for (Typedef typedef in _neededTypedefs) {
      return typedef;
    }
    Typedef typedef = Typedef('foo', DynamicType(), fileUri: _uri);
    _neededTypedefs.add(typedef);
    _needLibrary().addTypedef(typedef);
    return typedef;
  }

  /// Returns a [TypeParameter] node that fits the requirements.
  ///
  /// If no such [TypeParameter] exists in [_neededTypeParameters], a new
  /// [TypeParameter] is created and added to [_neededTypeParameters].
  // TODO(johnniwinther): Add requirements when/where needed.
  TypeParameter _needTypeParameter() {
    for (TypeParameter typeParameter in _neededTypeParameters) {
      return typeParameter;
    }
    TypeParameter typeParameter = TypeParameter(
      'foo',
      DynamicType(),
      DynamicType(),
    );
    _neededTypeParameters.add(typeParameter);
    // TODO(johnniwinther): Add the type parameter to a context; class, method
    // or function type.
    return typeParameter;
  }

  /// Returns a [StructuralParameter] node that fits the requirements.
  ///
  /// If no such [StructuralParameter] exists in
  /// [_neededStructuralParameters], a new [StructuralParameter] is
  /// created and added to [_neededStructuralParameters].
  // TODO(johnniwinther): Add requirements when/where needed.
  StructuralParameter _needStructuralParameter() {
    for (StructuralParameter typeParameter in _neededStructuralParameters) {
      return typeParameter;
    }
    StructuralParameter functionTypeTypeParameter = StructuralParameter(
      'foo',
      DynamicType(),
      DynamicType(),
    );
    _neededStructuralParameters.add(functionTypeTypeParameter);
    // TODO(johnniwinther): Add the type parameter to a context, that is,
    // function type.
    return functionTypeTypeParameter;
  }

  /// Returns a [Procedure] node that fits the requirements.
  ///
  /// If no such [Procedure] exists in [_neededProcedures], a new [Library] is
  /// created and added to [_neededProcedures].
  ///
  /// [index] is used to create multiple distinct [Procedure] nodes even when
  /// these have the same requirements.
  Procedure _needProcedure() {
    int? index = null;
    bool? isStatic = null;
    for (Procedure procedure in _neededProcedures) {
      if (isStatic == null || isStatic == procedure.isStatic) {
        if (index == null || index == 0) {
          return procedure;
        } else {
          index--;
        }
      }
    }
    isStatic ??= true;
    Procedure procedure = Procedure(
      Name('foo'),
      ProcedureKind.Method,
      FunctionNode(Block([])),
      fileUri: _uri,
      isStatic: isStatic,
    );
    _neededProcedures.add(procedure);
    if (isStatic) {
      _needLibrary().addProcedure(procedure);
    } else {
      _needClass().addProcedure(procedure);
    }
    return procedure;
  }

  /// Returns a [Constructor] node that fits the requirements.
  ///
  /// If no such [Constructor] exists in [_neededConstructors], a new
  /// [Constructor] is created and added to [_neededConstructors].
  // TODO(johnniwinther): Add requirements when/where needed.
  Constructor _needConstructor() {
    for (Constructor constructor in _neededConstructors) {
      return constructor;
    }
    Constructor constructor = Constructor(
      FunctionNode(null),
      name: Name('foo'),
      fileUri: _uri,
    );
    _needClass().addConstructor(constructor);
    return constructor;
  }

  /// Returns a redirecting factory [Procedure] node that fits the requirements.
  ///
  /// If no such [Library] exists in [_neededRedirectingFactories], a new
  /// [Procedure] is created and added to [_neededRedirectingFactories].
  // TODO(johnniwinther): Add requirements when/where needed.
  Procedure _needRedirectingFactory() {
    for (Procedure redirectingFactory in _neededRedirectingFactories) {
      return redirectingFactory;
    }
    Procedure redirectingFactory = Procedure(
      Name('foo'),
      ProcedureKind.Method,
      FunctionNode(null)
        ..redirectingFactoryTarget = new RedirectingFactoryTarget(
          _needConstructor(),
          [],
        ),
      fileUri: _uri,
    );
    _needClass().addProcedure(redirectingFactory);
    return redirectingFactory;
  }

  /// Returns a [Field] node that fits the requirements.
  ///
  /// If no such [Field] exists in [_neededFields], a new [Field] is
  /// created and added to [_neededFields].
  ///
  /// [index] is used to create multiple distinct [Field] nodes even when
  /// these have the same requirements.
  Field _needField({int? index, bool? isStatic, bool? hasSetter}) {
    for (Field field in _neededFields) {
      if (isStatic == null ||
          isStatic == field.isStatic && hasSetter == null ||
          hasSetter == field.hasSetter) {
        if (index == null || index == 0) {
          return field;
        } else {
          index--;
        }
      }
    }
    hasSetter ??= false;
    isStatic ??= true;
    Field field = hasSetter
        ? new Field.immutable(Name('foo'), fileUri: _uri, isStatic: isStatic)
        : new Field.mutable(Name('foo'), fileUri: _uri, isStatic: isStatic);
    _neededFields.add(field);
    if (isStatic) {
      _needLibrary().addField(field);
    } else {
      _needClass().addField(field);
    }
    return field;
  }

  /// Returns a [DeclaredVariable] node that fits the requirements.
  ///
  /// If no such [DeclaredVariable] exists in [_neededVariables],
  /// a new [DeclaredVariable] is created and added to
  /// [_neededVariables].
  // TODO(johnniwinther): Add requirements when/where needed.
  DeclaredVariable _needVariable() {
    for (DeclaredVariable variable in _neededVariables) {
      return variable;
    }
    DeclaredVariable variable = LocalVariable(name: 'foo', type: null);
    _neededVariables.add(variable);
    return variable;
  }

  /// Returns a [LabeledStatement] node that fits the requirements.
  ///
  /// If no such [LabeledStatement] exists in [_neededLabeledStatements], a new
  /// [LabeledStatement] is created and added to [_neededLabeledStatements].
  // TODO(johnniwinther): Add requirements when/where needed.
  LabeledStatement _needLabeledStatement() {
    for (LabeledStatement labeledStatement in _neededLabeledStatements) {
      return labeledStatement;
    }
    LabeledStatement labeledStatement = LabeledStatement(null);
    _neededLabeledStatements.add(labeledStatement);
    return labeledStatement;
  }

  /// Returns a [SwitchCase] node that fits the requirements.
  ///
  /// If no such [SwitchCase] exists in [_neededSwitchCases], a new [SwitchCase]
  /// is created and added to [_neededSwitchCases].
  // TODO(johnniwinther): Add requirements when/where needed.
  SwitchCase _needSwitchCase() {
    for (SwitchCase switchCase in _neededSwitchCases) {
      return switchCase;
    }
    SwitchCase switchCase = SwitchCase(
      [NullLiteral()],
      [TreeNode.noOffset],
      EmptyStatement(),
    );
    _neededSwitchCases.add(switchCase);
    return switchCase;
  }

  /// Returns a [FunctionDeclaration] node that fits the requirements.
  ///
  /// If no such [FunctionDeclaration] exists in [_neededFunctionDeclarations],
  /// a new [FunctionDeclaration] is created and added to
  /// [_neededFunctionDeclarations].
  // TODO(johnniwinther): Add requirements when/where needed.
  FunctionDeclaration _needFunctionDeclaration() {
    for (FunctionDeclaration functionDeclaration
        in _neededFunctionDeclarations) {
      return functionDeclaration;
    }
    FunctionDeclaration functionDeclaration = FunctionDeclaration(
      LocalFunctionVariable(name: 'foo'),
      FunctionNode(Block([])),
    );
    _neededFunctionDeclarations.add(functionDeclaration);
    return functionDeclaration;
  }

  /// Returns a fresh file offset value.
  int _needFileOffset() => _fileOffset++;

  /// Creates an [Expression] node.
  ///
  /// If there are any pending expressions, one of these is created.
  Expression _createExpression() {
    if (_pendingExpressions.isEmpty) {
      return NullLiteral()..fileOffset = _needFileOffset();
    }
    ExpressionKind kind = _pendingExpressions.keys.first;
    return _createExpressionFromKind(kind);
  }

  /// Creates an [Expression] node of the specified [kind].
  ///
  /// If there are any pending expressions of this [kind], one of these is
  /// created.
  Expression _createExpressionFromKind(ExpressionKind kind) {
    int? index = _pendingExpressions.remove(kind);
    switch (kind) {
      case ExpressionKind.AsExpression:
        return AsExpression(_createExpression(), _createDartType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.AwaitExpression:
        return AwaitExpression(_createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.BlockExpression:
        return BlockExpression(
          _createStatementFromKind(StatementKind.Block) as Block,
          _createExpression(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.BoolLiteral:
        return BoolLiteral(true)..fileOffset = _needFileOffset();
      case ExpressionKind.CheckLibraryIsLoaded:
        return CheckLibraryIsLoaded(_needLibraryDependency(deferred: true))
          ..fileOffset = _needFileOffset();
      case ExpressionKind.ConditionalExpression:
        return ConditionalExpression(
          _createExpression(),
          _createExpression(),
          _createExpression(),
          _createDartType(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.ConstantExpression:
        return ConstantExpression(_createConstant(), _createDartType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.ConstructorInvocation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => ConstructorInvocation(
            _needConstructor(),
            _createArguments(),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => ConstructorInvocation(
            _needConstructor(),
            _createArguments(),
            isConst: true,
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.ConstructorTearOff:
        return ConstructorTearOff(_needConstructor())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.DoubleLiteral:
        return DoubleLiteral(42.5)..fileOffset = _needFileOffset();
      case ExpressionKind.DynamicGet:
        return DynamicGet(
          DynamicAccessKind.Dynamic,
          _createExpression(),
          _createName(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.DynamicInvocation:
        return DynamicInvocation(
          DynamicAccessKind.Dynamic,
          _createExpression(),
          _createName(),
          _createArguments(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.DynamicSet:
        return DynamicSet(
          DynamicAccessKind.Dynamic,
          _createExpression(),
          _createName(),
          _createExpression(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.EqualsCall:
        return EqualsCall(
          _createExpression(),
          _createExpression(),
          functionType: _createFunctionType(),
          interfaceTarget: _needProcedure(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.EqualsNull:
        return EqualsNull(_createExpression())..fileOffset = _needFileOffset();
      case ExpressionKind.FileUriExpression:
        return FileUriExpression(_createExpression(), _uri)
          ..fileOffset = _needFileOffset();
      case ExpressionKind.FunctionExpression:
        return FunctionExpression(_createFunctionNode())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.FunctionInvocation:
        return FunctionInvocation(
          FunctionAccessKind.FunctionType,
          _createExpression(),
          _createArguments(),
          functionType: _createFunctionType(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.FunctionTearOff:
        return FunctionTearOff(_createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceCreation:
        return InstanceCreation(_needClass().reference, [], {}, [], [])
          ..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceGet:
        return InstanceGet(
          InstanceAccessKind.Instance,
          _createExpression(),
          _createName(),
          interfaceTarget: _needField(),
          resultType: _createDartType(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceGetterInvocation:
        return InstanceGetterInvocation(
          InstanceAccessKind.Instance,
          _createExpression(),
          _createName(),
          _createArguments(),
          interfaceTarget: _needField(),
          functionType: _createFunctionType(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceInvocation:
        return InstanceInvocation(
            InstanceAccessKind.Instance,
            _createExpression(),
            _createName(),
            _createArguments(),
            interfaceTarget: _needProcedure(),
            functionType: _createFunctionType(),
          )
          ..fileOffset = _needFileOffset()
          ..isBoundsSafe = true;
      case ExpressionKind.InstanceSet:
        return InstanceSet(
          InstanceAccessKind.Instance,
          _createExpression(),
          _createName(),
          _createExpression(),
          interfaceTarget: _needField(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceTearOff:
        return InstanceTearOff(
          InstanceAccessKind.Instance,
          _createExpression(),
          _createName(),
          interfaceTarget: _needProcedure(),
          resultType: _createDartType(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.Instantiation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () =>
              Instantiation(_createExpression(), [])
                ..fileOffset = _needFileOffset(),
          () =>
              Instantiation(_createExpression(), [_createDartType()])
                ..fileOffset = _needFileOffset(),
          () => Instantiation(_createExpression(), [
            _createDartType(),
            _createDartType(),
          ])..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.IntLiteral:
        return IntLiteral(42)..fileOffset = _needFileOffset();
      case ExpressionKind.InvalidExpression:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => InvalidExpression('foo')..fileOffset = _needFileOffset(),
          () =>
              InvalidExpression('foo', _createExpression())
                ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.IsExpression:
        return IsExpression(_createExpression(), _createDartType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.Let:
        return Let(
          _createVariableFromKind(VariableKind.SyntheticVariable)
              as SyntheticVariable,
          _createExpression(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.ListConcatenation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () =>
              ListConcatenation([], typeArgument: _createDartType())
                ..fileOffset = _needFileOffset(),
          () => ListConcatenation([
            _createExpression(),
          ], typeArgument: _createDartType())..fileOffset = _needFileOffset(),
          () => ListConcatenation([
            _createExpression(),
            _createExpression(),
          ], typeArgument: _createDartType())..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.ListLiteral:
        return _createOneOf(_pendingExpressions, kind, index, [
          () =>
              ListLiteral([], typeArgument: _createDartType(), isConst: false)
                ..fileOffset = _needFileOffset(),
          () => ListLiteral(
            [_createExpression()],
            typeArgument: _createDartType(),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => ListLiteral(
            [_createExpression(), _createExpression()],
            typeArgument: _createDartType(),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => ListLiteral(
            [_createExpression(), _createExpression()],
            typeArgument: _createDartType(),
            isConst: true,
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.LoadLibrary:
        return LoadLibrary(_needLibraryDependency(deferred: true))
          ..fileOffset = _needFileOffset();
      case ExpressionKind.LocalFunctionInvocation:
        return LocalFunctionInvocation(
          _needFunctionDeclaration().variable,
          _createArguments(),
          functionType: _createFunctionType(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.LogicalExpression:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => LogicalExpression(
            _createExpression(),
            LogicalExpressionOperator.AND,
            _createExpression(),
          )..fileOffset = _needFileOffset(),
          () => LogicalExpression(
            _createExpression(),
            LogicalExpressionOperator.OR,
            _createExpression(),
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.MapConcatenation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => MapConcatenation(
            [],
            keyType: _createDartType(),
            valueType: _createDartType(),
          )..fileOffset = _needFileOffset(),
          () => MapConcatenation(
            [_createExpression()],
            keyType: _createDartType(),
            valueType: _createDartType(),
          )..fileOffset = _needFileOffset(),
          () => MapConcatenation(
            [_createExpression(), _createExpression()],
            keyType: _createDartType(),
            valueType: _createDartType(),
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.MapLiteral:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => MapLiteral(
            [],
            keyType: _createDartType(),
            valueType: _createDartType(),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => MapLiteral(
            [_createMapLiteralEntry()],
            keyType: _createDartType(),
            valueType: _createDartType(),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => MapLiteral(
            [_createMapLiteralEntry(), _createMapLiteralEntry()],
            keyType: _createDartType(),
            valueType: _createDartType(),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => MapLiteral(
            [_createMapLiteralEntry(), _createMapLiteralEntry()],
            keyType: _createDartType(),
            valueType: _createDartType(),
            isConst: true,
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.Not:
        return Not(_createExpression())..fileOffset = _needFileOffset();
      case ExpressionKind.NullCheck:
        return NullCheck(_createExpression())..fileOffset = _needFileOffset();
      case ExpressionKind.NullLiteral:
        return NullLiteral();
      case ExpressionKind.RedirectingFactoryTearOff:
        return RedirectingFactoryTearOff(_needRedirectingFactory())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.Rethrow:
        return Rethrow()..fileOffset = _needFileOffset();
      case ExpressionKind.SetConcatenation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () =>
              SetConcatenation([], typeArgument: _createDartType())
                ..fileOffset = _needFileOffset(),
          () => SetConcatenation([
            _createExpression(),
          ], typeArgument: _createDartType())..fileOffset = _needFileOffset(),
          () => SetConcatenation([
            _createExpression(),
            _createExpression(),
          ], typeArgument: _createDartType())..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SetLiteral:
        return _createOneOf(_pendingExpressions, kind, index, [
          () =>
              SetLiteral([], typeArgument: _createDartType(), isConst: false)
                ..fileOffset = _needFileOffset(),
          () => SetLiteral(
            [_createExpression()],
            typeArgument: _createDartType(),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => SetLiteral(
            [_createExpression(), _createExpression()],
            typeArgument: _createDartType(),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => SetLiteral(
            [_createExpression(), _createExpression()],
            typeArgument: _createDartType(),
            isConst: true,
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.StaticGet:
        return StaticGet(_needField())..fileOffset = _needFileOffset();
      case ExpressionKind.StaticInvocation:
        return StaticInvocation(_needProcedure(), _createArguments())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.StaticSet:
        return StaticSet(_needField(), _createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.StaticTearOff:
        return StaticTearOff(_needProcedure())..fileOffset = _needFileOffset();
      case ExpressionKind.StringConcatenation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => StringConcatenation([])..fileOffset = _needFileOffset(),
          () =>
              StringConcatenation([_createExpression()])
                ..fileOffset = _needFileOffset(),
          () =>
              StringConcatenation([_createExpression(), _createExpression()])
                ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.StringLiteral:
        return StringLiteral('foo');
      case ExpressionKind.AbstractSuperMethodInvocation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => AbstractSuperMethodInvocation(
            new ThisExpression(),
            _createName(),
            _createArguments(),
            _needProcedure(),
          )..fileOffset = _needFileOffset(),
          () => AbstractSuperMethodInvocation(
            new ThisExpression(),
            _createName(),
            _createArguments(),
            _needProcedure(),
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SuperMethodInvocation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => SuperMethodInvocation(
            new ThisExpression(),
            _createName(),
            _createArguments(),
            _needProcedure(),
          )..fileOffset = _needFileOffset(),
          () => SuperMethodInvocation(
            new ThisExpression(),
            _createName(),
            _createArguments(),
            _needProcedure(),
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.AbstractSuperPropertyGet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => AbstractSuperPropertyGet(
            new ThisExpression(),
            _createName(),
            _needProcedure(),
          )..fileOffset = _needFileOffset(),
          () => AbstractSuperPropertyGet(
            new ThisExpression(),
            _createName(),
            _needField(),
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.AbstractSuperPropertySet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => AbstractSuperPropertySet(
            new ThisExpression(),
            _createName(),
            _createExpression(),
            _needProcedure(),
          )..fileOffset = _needFileOffset(),
          () => AbstractSuperPropertySet(
            new ThisExpression(),
            _createName(),
            _createExpression(),
            _needField(),
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SuperPropertyGet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => SuperPropertyGet(
            new ThisExpression(),
            _createName(),
            _needProcedure(),
          )..fileOffset = _needFileOffset(),
          () => SuperPropertyGet(
            new ThisExpression(),
            _createName(),
            _needField(),
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SuperPropertySet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => SuperPropertySet(
            new ThisExpression(),
            _createName(),
            _createExpression(),
            _needProcedure(),
          )..fileOffset = _needFileOffset(),
          () => SuperPropertySet(
            new ThisExpression(),
            _createName(),
            _createExpression(),
            _needField(),
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SymbolLiteral:
        return SymbolLiteral('foo')..fileOffset = _needFileOffset();
      case ExpressionKind.ThisExpression:
        return ThisExpression()..fileOffset = _needFileOffset();
      case ExpressionKind.Throw:
        return Throw(_createExpression())..fileOffset = _needFileOffset();
      case ExpressionKind.TypeLiteral:
        return TypeLiteral(_createDartType())..fileOffset = _needFileOffset();
      case ExpressionKind.TypedefTearOff:
        // TODO(johnniwinther): Add non-trivial cases.
        return TypedefTearOff([], _createExpression(), [])
          ..fileOffset = _needFileOffset();
      case ExpressionKind.VariableGet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => VariableGet(_needVariable())..fileOffset = _needFileOffset(),
          () =>
              VariableGet(_needVariable(), _createDartType())
                ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.VariableSet:
        return VariableSet(_needVariable(), _createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.RecordIndexGet:
        return RecordIndexGet(
          _createExpression(),
          new RecordType([_createDartType()], [], Nullability.nonNullable),
          0,
        )..fileOffset = _needFileOffset();
      case ExpressionKind.RecordNameGet:
        String name = _createName().text;
        return RecordNameGet(
          _createExpression(),
          new RecordType([], [
            new NamedType(name, _createDartType()),
          ], Nullability.nonNullable),
          name,
        )..fileOffset = _needFileOffset();
      case ExpressionKind.RecordLiteral:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => RecordLiteral(
            [_createExpression()],
            [],
            RecordType([_createDartType()], [], Nullability.nonNullable),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => RecordLiteral(
            [],
            [NamedExpression('foo', _createExpression())],
            RecordType([], [
              NamedType('foo', _createDartType()),
            ], Nullability.nonNullable),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => RecordLiteral(
            [_createExpression()],
            [NamedExpression('foo', _createExpression())],
            RecordType(
              [_createDartType()],
              [NamedType('foo', _createDartType())],
              Nullability.nonNullable,
            ),
            isConst: false,
          )..fileOffset = _needFileOffset(),
          () => RecordLiteral(
            [_createExpression()],
            [],
            RecordType([_createDartType()], [], Nullability.nonNullable),
            isConst: true,
          )..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SwitchExpression:
        return _createOneOf(_pendingExpressions, kind, index, [
          () =>
              new SwitchExpression(_createExpression(), [])
                ..fileOffset = _needFileOffset(),
          () => new SwitchExpression(_createExpression(), [
            _createNodeFromKind(NodeKind.SwitchExpressionCase)
                as SwitchExpressionCase,
          ])..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.PatternAssignment:
        return new PatternAssignment(_createPattern(), _createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.RedirectingFactoryInvocation:
        return new RedirectingFactoryInvocation(
          _needRedirectingFactory(),
          _createExpressionFromKind(ExpressionKind.ConstructorInvocation)
              as InvocationExpression,
        );
    }
  }

  /// Creates an [Pattern] node.
  ///
  /// If there are any pending expressions, one of these is created.
  Pattern _createPattern() {
    if (_pendingPatterns.isEmpty) {
      return ConstantPattern(NullLiteral()..fileOffset = _needFileOffset())
        ..fileOffset = _needFileOffset();
    }
    PatternKind kind = _pendingPatterns.keys.first;
    return _createPatternFromKind(kind);
  }

  /// Creates an [Expression] node of the specified [kind].
  ///
  /// If there are any pending expressions of this [kind], one of these is
  /// created.
  Pattern _createPatternFromKind(PatternKind kind) {
    int? index = _pendingPatterns.remove(kind);
    switch (kind) {
      case PatternKind.AndPattern:
        return AndPattern(_createPattern(), _createPattern())
          ..fileOffset = _needFileOffset();
      case PatternKind.AssignedVariablePattern:
        return AssignedVariablePattern(_needVariable())
          ..fileOffset = _needFileOffset();
      case PatternKind.CastPattern:
        return CastPattern(_createPattern(), _createDartType())
          ..fileOffset = _needFileOffset();
      case PatternKind.ConstantPattern:
        return ConstantPattern(_createExpression())
          ..fileOffset = _needFileOffset();
      case PatternKind.NullAssertPattern:
        return NullAssertPattern(_createPattern())
          ..fileOffset = _needFileOffset();
      case PatternKind.NullCheckPattern:
        return NullCheckPattern(_createPattern())
          ..fileOffset = _needFileOffset();
      case PatternKind.InvalidPattern:
        return InvalidPattern(_createExpression(), declaredVariables: [])
          ..fileOffset = _needFileOffset();
      case PatternKind.ListPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => ListPattern(null, [])..fileOffset = _needFileOffset(),
          () =>
              ListPattern(_createDartType(), [_createPattern()])
                ..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.MapPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => MapPattern(null, null, []),
          () => MapPattern(_createDartType(), _createDartType(), [
            _createNodeFromKind(NodeKind.MapPatternEntry) as MapPatternEntry,
          ])..fileOffset = _needFileOffset(),
          () => MapPattern(_createDartType(), _createDartType(), [
            _createNodeFromKind(NodeKind.MapPatternEntry) as MapPatternEntry,
            _createNodeFromKind(NodeKind.MapPatternRestEntry)
                as MapPatternEntry,
          ])..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.NamedPattern:
        return NamedPattern('foo', _createPattern())
          ..fileOffset = _needFileOffset();
      case PatternKind.ObjectPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () =>
              ObjectPattern(_createDartType(), [])
                ..fileOffset = _needFileOffset(),
          () => ObjectPattern(_createDartType(), [
            _createPatternFromKind(PatternKind.NamedPattern) as NamedPattern,
          ])..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.OrPattern:
        return OrPattern(
          _createPattern(),
          _createPattern(),
          orPatternJointVariables: [],
        )..fileOffset = _needFileOffset();
      case PatternKind.RecordPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => RecordPattern([])..fileOffset = _needFileOffset(),
          () =>
              RecordPattern([_createPattern()])..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.RelationalPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => RelationalPattern(
            RelationalPatternKind.equals,
            _createExpression(),
          )..fileOffset = _needFileOffset(),
          () => RelationalPattern(
            RelationalPatternKind.lessThan,
            _createExpression(),
          )..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.RestPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => RestPattern(null)..fileOffset = _needFileOffset(),
          () => RestPattern(_createPattern())..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.VariablePattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => VariablePattern(
            null,
            _createVariableFromKind(VariableKind.LocalVariable)
                as DeclaredVariable,
          )..fileOffset = _needFileOffset(),
          () => VariablePattern(
            _createDartType(),
            _createVariableFromKind(VariableKind.LocalVariable)
                as DeclaredVariable,
          )..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.WildcardPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => WildcardPattern(null)..fileOffset = _needFileOffset(),
          () =>
              WildcardPattern(_createDartType())
                ..fileOffset = _needFileOffset(),
        ]);
    }
  }

  /// Creates a [Statement] node.
  ///
  /// If there are any pending statements, one of these is created.
  Statement _createStatement() {
    if (_pendingStatements.isEmpty) {
      return EmptyStatement()..fileOffset = _needFileOffset();
    }
    StatementKind kind = _pendingStatements.keys.first;
    return _createStatementFromKind(kind);
  }

  /// Creates a [Statement] of the specified [kind].
  ///
  /// If there are any pending statements of this [kind], one of these is
  /// created.
  Statement _createStatementFromKind(StatementKind kind) {
    int? index = _pendingStatements.remove(kind);
    switch (kind) {
      case StatementKind.AssertBlock:
        return _createOneOf(_pendingStatements, kind, index, [
          () => AssertBlock([])..fileOffset = _needFileOffset(),
          () =>
              AssertBlock([_createStatement()])..fileOffset = _needFileOffset(),
          () =>
              AssertBlock([_createStatement(), _createStatement()])
                ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.AssertStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => AssertStatement(
            _createExpression(),
            conditionStartOffset: _needFileOffset(),
            conditionEndOffset: _needFileOffset(),
          )..fileOffset = _needFileOffset(),
          () => AssertStatement(
            _createExpression(),
            message: _createExpression(),
            conditionStartOffset: _needFileOffset(),
            conditionEndOffset: _needFileOffset(),
          )..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.Block:
        return _createOneOf(_pendingStatements, kind, index, [
          () => Block([])..fileOffset = _needFileOffset(),
          () => Block([_createStatement()])..fileOffset = _needFileOffset(),
          () =>
              Block([_createStatement(), _createStatement()])
                ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.BreakStatement:
        return BreakStatement(_needLabeledStatement())
          ..fileOffset = _needFileOffset();
      case StatementKind.ContinueSwitchStatement:
        return ContinueSwitchStatement(_needSwitchCase())
          ..fileOffset = _needFileOffset();
      case StatementKind.DoStatement:
        return DoStatement(_createStatement(), _createExpression())
          ..fileOffset = _needFileOffset();
      case StatementKind.EmptyStatement:
        return EmptyStatement()..fileOffset = _needFileOffset();
      case StatementKind.ExpressionStatement:
        return ExpressionStatement(_createExpression())
          ..fileOffset = _needFileOffset();
      case StatementKind.ForInStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => ForInStatement(
            _createVariableFromKind(VariableKind.LocalVariable)
                as DeclaredVariable,
            _createExpression(),
            _createStatement(),
            isAsync: false,
          )..fileOffset = _needFileOffset(),
          () => ForInStatement(
            _createVariableFromKind(VariableKind.LocalVariable)
                as DeclaredVariable,
            _createExpression(),
            _createStatement(),
            isAsync: true,
          )..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.ForStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () =>
              ForStatement([], null, [], _createStatement())
                ..fileOffset = _needFileOffset(),
          () => ForStatement(
            [
              VariableDeclaration(
                _createVariableFromKind(VariableKind.LocalVariable)
                    as DeclaredVariable,
              ),
            ],
            _createExpression(),
            [_createExpression()],
            _createStatement(),
          )..fileOffset = _needFileOffset(),
          () => ForStatement(
            [
              VariableDeclaration(
                _createVariableFromKind(VariableKind.LocalVariable)
                    as DeclaredVariable,
              ),
              VariableDeclaration(
                _createVariableFromKind(VariableKind.LocalVariable)
                    as DeclaredVariable,
              ),
            ],
            _createExpression(),
            [_createExpression(), _createExpression()],
            _createStatement(),
          )..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.FunctionDeclaration:
        return FunctionDeclaration(
          LocalFunctionVariable(name: 'foo'),
          _createFunctionNode(),
        )..fileOffset = _needFileOffset();
      case StatementKind.IfStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () =>
              IfStatement(_createExpression(), _createStatement(), null)
                ..fileOffset = _needFileOffset(),
          () => IfStatement(
            _createExpression(),
            _createStatement(),
            _createStatement(),
          )..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.LabeledStatement:
        return LabeledStatement(_createStatement())
          ..fileOffset = _needFileOffset();
      case StatementKind.ReturnStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => ReturnStatement()..fileOffset = _needFileOffset(),
          () =>
              ReturnStatement(_createExpression())
                ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.SwitchStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () =>
              SwitchStatement(_createExpression(), [])
                ..fileOffset = _needFileOffset(),
          () =>
              SwitchStatement(_createExpression(), [_createSwitchCase()])
                ..fileOffset = _needFileOffset(),
          () => SwitchStatement(_createExpression(), [
            _createSwitchCase(),
            _createSwitchCase(),
          ])..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.TryCatch:
        return _createOneOf(_pendingStatements, kind, index, [
          () =>
              TryCatch(_createStatement(), [])..fileOffset = _needFileOffset(),
          () =>
              TryCatch(_createStatement(), [_createCatch()])
                ..fileOffset = _needFileOffset(),
          () =>
              TryCatch(_createStatement(), [_createCatch(), _createCatch()])
                ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.TryFinally:
        return TryFinally(_createStatement(), _createStatement())
          ..fileOffset = _needFileOffset();
      case StatementKind.VariableStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => VariableStatement(
            VariableDeclaration(
              LocalVariable(name: 'foo')..fileOffset = _needFileOffset(),
            )..fileOffset = _needFileOffset(),
          )..fileOffset = _needFileOffset(),
          () => VariableStatement(
            VariableDeclaration(
              LocalVariable(name: 'foo', initializer: _createExpression())
                ..fileOffset = _needFileOffset(),
            )..fileOffset = _needFileOffset(),
          )..fileOffset = _needFileOffset(),
          () => VariableStatement(
            VariableDeclaration(
              LocalVariable(name: 'foo', type: _createDartType())
                ..fileOffset = _needFileOffset(),
            )..fileOffset = _needFileOffset(),
          )..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.WhileStatement:
        return WhileStatement(_createExpression(), _createStatement())
          ..fileOffset = _needFileOffset();
      case StatementKind.YieldStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () =>
              YieldStatement(_createExpression(), isYieldStar: false)
                ..fileOffset = _needFileOffset(),
          () =>
              YieldStatement(_createExpression(), isYieldStar: true)
                ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.PatternSwitchStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () =>
              PatternSwitchStatement(_createExpression(), [])
                ..fileOffset = _needFileOffset(),
          () => PatternSwitchStatement(_createExpression(), [
            _createNodeFromKind(NodeKind.PatternSwitchCase)
                as PatternSwitchCase,
          ])..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.IfCaseStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => IfCaseStatement(
            _createExpression(),
            _createNodeFromKind(NodeKind.PatternGuard) as PatternGuard,
            _createStatement(),
          )..fileOffset = _needFileOffset(),
          () => IfCaseStatement(
            _createExpression(),
            _createNodeFromKind(NodeKind.PatternGuard) as PatternGuard,
            _createStatement(),
            _createStatement(),
          )..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.PatternVariableDeclaration:
        return _createOneOf(_pendingStatements, kind, index, [
          () => new PatternVariableDeclaration(
            _createPattern(),
            _createExpression(),
            isFinal: false,
          )..fileOffset = _needFileOffset(),
          () => new PatternVariableDeclaration(
            _createPattern(),
            _createExpression(),
            isFinal: true,
          )..fileOffset = _needFileOffset(),
        ]);
    }
  }

  /// Creates a [Variable] node.
  ///
  /// If there are any pending [Variable] nodes, one of these is
  /// created.
  Variable _createVariableFromKind(VariableKind kind) {
    int? index = _pendingVariables.remove(kind);
    switch (kind) {
      case VariableKind.CatchVariable:
        return CatchVariable(name: 'e');
      case VariableKind.LateVariable:
        return LateVariable(name: 'foo');
      case VariableKind.LocalFunctionVariable:
        return LocalFunctionVariable(name: 'foo');
      case VariableKind.ConstVariable:
        return ConstVariable(name: 'foo');
      case VariableKind.LocalVariable:
        return _createOneOf(_pendingVariables, kind, index, [
          () => LocalVariable(name: 'foo')..fileOffset = _needFileOffset(),

          () =>
              LocalVariable(name: 'foo', initializer: _createExpression())
                ..fileOffset = _needFileOffset(),
          () =>
              LocalVariable(name: 'foo', type: _createDartType())
                ..fileOffset = _needFileOffset(),
        ]);
      case VariableKind.NamedParameter:
        return NamedParameter(parameterName: 'foo');
      case VariableKind.PositionalParameter:
        return PositionalParameter();
      case VariableKind.SyntheticVariable:
        return SyntheticVariable();
      case VariableKind.ThisVariable:
        return ThisVariable(type: _createDartType());
    }
  }

  /// Creates a [DartType] node.
  ///
  /// If there are any pending types, one of these is created.
  DartType _createDartType() {
    if (_pendingDartTypes.isEmpty) {
      return VoidType();
    }
    DartTypeKind kind = _pendingDartTypes.keys.first;
    return _createDartTypeFromKind(kind);
  }

  /// Creates a [DartType] node of the specified [kind].
  ///
  /// If there are any pending types of this [kind], one of these is created.
  DartType _createDartTypeFromKind(DartTypeKind kind) {
    int? index = _pendingDartTypes.remove(kind);
    switch (kind) {
      case DartTypeKind.DynamicType:
        return DynamicType();
      case DartTypeKind.FunctionType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          // TODO(johnniwinther): Create non-trivial cases.
          () => FunctionType([], _createDartType(), Nullability.nonNullable),
        ]);
      case DartTypeKind.RecordType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          // TODO(cstefantsova): Create non-trivial cases.
          () => RecordType([], [], Nullability.nonNullable),
        ]);
      case DartTypeKind.FutureOrType:
        return FutureOrType(_createDartType(), Nullability.nonNullable);
      case DartTypeKind.InterfaceType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          // TODO(johnniwinther): Create non-trivial cases.
          () => InterfaceType(_needClass(), Nullability.nonNullable, []),
        ]);
      case DartTypeKind.InvalidType:
        return InvalidType();
      case DartTypeKind.NeverType:
        return NeverType.nonNullable();
      case DartTypeKind.NullType:
        return NullType();
      case DartTypeKind.TypeParameterType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          () =>
              TypeParameterType(_needTypeParameter(), Nullability.nonNullable),
        ]);
      case DartTypeKind.StructuralParameterType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          () => StructuralParameterType(
            _needStructuralParameter(),
            Nullability.nonNullable,
          ),
        ]);
      case DartTypeKind.IntersectionType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          () => IntersectionType(
            TypeParameterType(_needTypeParameter(), Nullability.nonNullable),
            _createDartType(),
          ),
        ]);
      case DartTypeKind.TypedefType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          // TODO(johnniwinther): Create non-trivial cases.
          () => TypedefType(_needTypedef(), Nullability.nonNullable, []),
        ]);
      case DartTypeKind.ExtensionType:
        return ExtensionType(
          _needExtensionTypeDeclaration(),
          Nullability.nonNullable,
        );
      case DartTypeKind.VoidType:
        return VoidType();
      case DartTypeKind.FunctionTypeParameterType:
        throw new UnimplementedError("Unimplemented support for $kind.");
      case DartTypeKind.ClassTypeParameterType:
        throw new UnimplementedError("Unimplemented support for $kind.");
    }
  }

  /// Creates a [FunctionType] node.
  ///
  /// If there are any pending [FunctionType] nodes, one of these is created.
  FunctionType _createFunctionType() {
    return _createDartTypeFromKind(DartTypeKind.FunctionType) as FunctionType;
  }

  /// Creates a [Constant] node.
  ///
  /// If there are any pending constants, one of these is created.
  Constant _createConstant() {
    if (_pendingConstants.isEmpty) {
      return NullConstant();
    }
    ConstantKind kind = _pendingConstants.keys.first;
    return _createConstantFromKind(kind);
  }

  /// Creates a [Constant] node of the specified [kind].
  ///
  /// If there are any pending constants of this [kind], one of these is
  /// created.
  Constant _createConstantFromKind(ConstantKind kind) {
    int? index = _pendingConstants.remove(kind);
    switch (kind) {
      case ConstantKind.BoolConstant:
        return BoolConstant(true);
      case ConstantKind.ConstructorTearOffConstant:
        return ConstructorTearOffConstant(_needConstructor());
      case ConstantKind.DoubleConstant:
        return DoubleConstant(42.5);
      case ConstantKind.InstanceConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => InstanceConstant(_needClass().reference, [], {}),
          () => InstanceConstant(
            _needClass().reference,
            [_createDartType()],
            {
              _needField(isStatic: false, hasSetter: false).getterReference:
                  _createConstant(),
            },
          ),
          () => InstanceConstant(
            _needClass().reference,
            [_createDartType()],
            {
              _needField(
                index: 0,
                isStatic: false,
                hasSetter: false,
              ).getterReference: _createConstant(),
              _needField(
                index: 1,
                isStatic: false,
                hasSetter: false,
              ).getterReference: _createConstant(),
            },
          ),
        ]);
      case ConstantKind.InstantiationConstant:
        return InstantiationConstant(_createConstant(), [_createDartType()]);
      case ConstantKind.IntConstant:
        return IntConstant(42);
      case ConstantKind.ListConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => ListConstant(_createDartType(), []),
          () => ListConstant(_createDartType(), [_createConstant()]),
          () => ListConstant(_createDartType(), [
            _createConstant(),
            _createConstant(),
          ]),
        ]);
      case ConstantKind.MapConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => MapConstant(_createDartType(), _createDartType(), []),
          () => MapConstant(_createDartType(), _createDartType(), [
            ConstantMapEntry(_createConstant(), _createConstant()),
          ]),
          () => MapConstant(_createDartType(), _createDartType(), [
            ConstantMapEntry(_createConstant(), _createConstant()),
            ConstantMapEntry(_createConstant(), _createConstant()),
          ]),
        ]);
      case ConstantKind.RecordConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => RecordConstant(
            [],
            {},
            RecordType([], [], Nullability.nonNullable),
          ),
          () => RecordConstant(
            [_createConstant(), _createConstant()],
            {},
            RecordType(
              [_createDartType(), _createDartType()],
              [],
              Nullability.nonNullable,
            ),
          ),
          () => RecordConstant(
            [],
            {'a': _createConstant(), 'b': _createConstant()},
            RecordType([], [
              NamedType('a', _createDartType()),
              NamedType('b', _createDartType()),
            ], Nullability.nonNullable),
          ),
          () => RecordConstant(
            [_createConstant()],
            {'a': _createConstant()},
            RecordType(
              [_createDartType()],
              [NamedType('a', _createDartType())],
              Nullability.nonNullable,
            ),
          ),
        ]);
      case ConstantKind.NullConstant:
        return NullConstant();
      case ConstantKind.RedirectingFactoryTearOffConstant:
        return RedirectingFactoryTearOffConstant(_needRedirectingFactory());
      case ConstantKind.SetConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => SetConstant(_createDartType(), []),
          () => SetConstant(_createDartType(), [_createConstant()]),
          () => SetConstant(_createDartType(), [
            _createConstant(),
            _createConstant(),
          ]),
        ]);
      case ConstantKind.StaticTearOffConstant:
        return StaticTearOffConstant(_needProcedure());
      case ConstantKind.StringConstant:
        return StringConstant('foo');
      case ConstantKind.SymbolConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => SymbolConstant('foo', null),
          () => SymbolConstant('_foo', _needLibrary().reference),
        ]);
      case ConstantKind.TypeLiteralConstant:
        return TypeLiteralConstant(_createDartType());
      case ConstantKind.TypedefTearOffConstant:
        // TODO(johnniwinther): Add non-trivial cases.
        return TypedefTearOffConstant(
          [],
          _createConstantFromKind(ConstantKind.ConstructorTearOffConstant)
              as TearOffConstant,
          [],
        );
      case ConstantKind.UnevaluatedConstant:
        return UnevaluatedConstant(_createExpression());
    }
  }

  /// Creates an [Initializer] node.
  ///
  /// If there are any pending initializers, one of these is created.
  Initializer _createInitializer() {
    if (_pendingInitializers.isEmpty) {
      return InvalidInitializer('')..fileOffset = _needFileOffset();
    }
    InitializerKind kind = _pendingInitializers.keys.first;
    return _createInitializerFromKind(kind);
  }

  /// Creates an [Initializer] node of the specified [kind].
  ///
  /// If there are any pending initializers of this [kind], one of these is
  /// created.
  Initializer _createInitializerFromKind(InitializerKind kind) {
    // ignore: unused_local_variable
    int? index = _pendingInitializers.remove(kind);
    switch (kind) {
      case InitializerKind.AssertInitializer:
        return AssertInitializer(
          _createStatementFromKind(StatementKind.AssertStatement)
              as AssertStatement,
        )..fileOffset = _needFileOffset();
      case InitializerKind.FieldInitializer:
        return FieldInitializer(
          _needField(isStatic: false),
          _createExpression(),
        )..fileOffset = _needFileOffset();
      case InitializerKind.InvalidInitializer:
        return InvalidInitializer('')..fileOffset = _needFileOffset();
      case InitializerKind.LocalInitializer:
        return LocalInitializer(
          _createVariableFromKind(VariableKind.SyntheticVariable)
              as SyntheticVariable,
        )..fileOffset = _needFileOffset();
      case InitializerKind.RedirectingInitializer:
        return RedirectingInitializer(_needConstructor(), _createArguments())
          ..fileOffset = _needFileOffset();
      case InitializerKind.SuperInitializer:
        return SuperInitializer(_needConstructor(), _createArguments())
          ..fileOffset = _needFileOffset();
    }
  }

  /// Creates a [Member] node.
  ///
  /// If there are any pending members, one of these is created.
  Member _createMember() {
    if (_pendingMembers.isEmpty) {
      return Field.immutable(_createName(), fileUri: _uri)
        ..fileOffset = _needFileOffset();
    }
    MemberKind kind = _pendingMembers.keys.first;
    return _createMemberKind(kind);
  }

  /// Creates a [Member] node of the specified [kind].
  ///
  /// If there are any pending members of this [kind], one of these is created.
  Member _createMemberKind(MemberKind kind) {
    int? index = _pendingMembers.remove(kind);
    switch (kind) {
      case MemberKind.Constructor:
        return Constructor(
          _createFunctionNode(),
          name: _createName(),
          fileUri: _uri,
        )..fileOffset = _needFileOffset();
      case MemberKind.Field:
        return _createOneOf(_pendingMembers, kind, index, [
          () =>
              Field.mutable(_createName(), fileUri: _uri)
                ..fileOffset = _needFileOffset(),
          () =>
              Field.immutable(_createName(), fileUri: _uri)
                ..fileOffset = _needFileOffset(),
        ]);
      case MemberKind.Procedure:
        return _createOneOf(_pendingMembers, kind, index, [
          () => Procedure(
            _createName(),
            ProcedureKind.Method,
            _createFunctionNode(),
            fileUri: _uri,
          )..fileOffset = _needFileOffset(),
          () => Procedure(
            _createName(),
            ProcedureKind.Operator,
            _createFunctionNode(),
            fileUri: _uri,
          )..fileOffset = _needFileOffset(),
          () => Procedure(
            _createName(),
            ProcedureKind.Getter,
            _createFunctionNode(),
            fileUri: _uri,
          )..fileOffset = _needFileOffset(),
          () => Procedure(
            _createName(),
            ProcedureKind.Setter,
            _createFunctionNode(),
            fileUri: _uri,
          )..fileOffset = _needFileOffset(),
        ]);
    }
  }

  /// Creates an [Arguments] node.
  ///
  /// If there are any pending [Arguments] nodes, one of these is created.
  Arguments _createArguments() {
    return _createNodeFromKind(NodeKind.Arguments) as Arguments;
  }

  /// Creates a [Name] node.
  ///
  /// If there are any pending [Name] nodes, one of these is created.
  Name _createName() {
    return _createNodeFromKind(NodeKind.Name) as Name;
  }

  /// Creates a [FunctionNode] node.
  ///
  /// If there are any pending [FunctionNode] nodes, one of these is created.
  FunctionNode _createFunctionNode() {
    return _createNodeFromKind(NodeKind.FunctionNode) as FunctionNode;
  }

  /// Creates a [MapLiteralEntry] node.
  ///
  /// If there are any pending [MapLiteralEntry] nodes, one of these is created.
  MapLiteralEntry _createMapLiteralEntry() {
    return _createNodeFromKind(NodeKind.MapLiteralEntry) as MapLiteralEntry;
  }

  /// Creates a [SwitchCase] node.
  ///
  /// If there are any pending [SwitchCase] nodes, one of these is created.
  SwitchCase _createSwitchCase() {
    return _createNodeFromKind(NodeKind.SwitchCase) as SwitchCase;
  }

  /// Creates a [Catch] node.
  ///
  /// If there are any pending [Catch] nodes, one of these is created.
  Catch _createCatch() {
    return _createNodeFromKind(NodeKind.Catch) as Catch;
  }

  /// Creates a [Node] of the specified [kind].
  ///
  /// If there are any pending nodes of this [kind], one of these is created.
  Node _createNodeFromKind(NodeKind kind) {
    int? index = _pendingNodes.remove(kind);
    switch (kind) {
      case NodeKind.Arguments:
        return _createOneOf(_pendingNodes, kind, index, [
          // TODO(johnniwinther): Add non-trivial cases.
          () => Arguments([])..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.Catch:
        return _createOneOf(_pendingNodes, kind, index, [
          () => Catch(null, _createStatement())..fileOffset = _needFileOffset(),
          () => Catch(
            _createVariableFromKind(VariableKind.CatchVariable)
                as CatchVariable,
            _createStatement(),
          )..fileOffset = _needFileOffset(),
          () => Catch(
            null,
            _createStatement(),
            stackTrace: _createVariableFromKind(
              VariableKind.CatchVariable,
            ) as CatchVariable,
          )..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.Class:
        return Class(name: 'foo', fileUri: _uri)
          ..fileOffset = _needFileOffset();
      case NodeKind.Combinator:
        return _createOneOf(_pendingNodes, kind, index, [
          () => Combinator.show([])..fileOffset = _needFileOffset(),
          () => Combinator.show(['foo'])..fileOffset = _needFileOffset(),
          () => Combinator.show(['foo', 'bar'])..fileOffset = _needFileOffset(),
          () => Combinator.hide([])..fileOffset = _needFileOffset(),
          () => Combinator.hide(['foo'])..fileOffset = _needFileOffset(),
          () => Combinator.hide(['foo', 'bar'])..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.Component:
        return _component;
      case NodeKind.Extension:
        // TODO(johnniwinther): Add non-trivial cases.
        return Extension(name: 'foo', fileUri: _uri)
          ..fileOffset = _needFileOffset()
          ..onType = _createDartType();
      case NodeKind.FunctionNode:
        return _createOneOf(_pendingNodes, kind, index, [
          () =>
              FunctionNode(_createStatement())..fileOffset = _needFileOffset(),
          () => FunctionNode(
            _createStatement(),
            positionalParameters: [
              _createVariableFromKind(VariableKind.PositionalParameter)
                  as PositionalParameter,
            ],
          )..fileOffset = _needFileOffset(),
          () => FunctionNode(
            _createStatement(),
            namedParameters: [
              _createVariableFromKind(VariableKind.NamedParameter)
                  as NamedParameter,
            ],
          )..fileOffset = _needFileOffset(),
          () => FunctionNode(
            _createStatement(),
            thisVariable: _createVariableFromKind(
              VariableKind.ThisVariable,
            ) as ThisVariable,
          )..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.Library:
        return Library(_uri, fileUri: _uri)..fileOffset = _needFileOffset();
      case NodeKind.LibraryDependency:
        return _createOneOf(_pendingNodes, kind, index, [
          // TODO(johnniwinther): Add more cases.
          () =>
              LibraryDependency.import(_needLibrary())
                ..fileOffset = _needFileOffset(),
          () =>
              LibraryDependency.import(_needLibrary(), name: 'foo')
                ..fileOffset = _needFileOffset(),
          () =>
              LibraryDependency.export(_needLibrary())
                ..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.LibraryPart:
        // TODO(johnniwinther): Add non-trivial cases.
        // TODO(johnniwinther): Do we need to use a valid part uri?
        return LibraryPart([], 'foo')..fileOffset = _needFileOffset();
      case NodeKind.MapLiteralEntry:
        return MapLiteralEntry(_createExpression(), _createExpression())
          ..fileOffset = _needFileOffset();
      case NodeKind.Name:
        return _createOneOf(_pendingNodes, kind, index, [
          () => Name('foo'),
          () => Name('_foo', _needLibrary()),
        ]);
      case NodeKind.NamedExpression:
        return NamedExpression('foo', _createExpression())
          ..fileOffset = _needFileOffset();
      case NodeKind.NamedType:
        return NamedType('foo', _createDartType());
      case NodeKind.Supertype:
        return _createOneOf(_pendingNodes, kind, index, [
          () => Supertype(_needClass(), []),
          () => Supertype(_needClass(), [_createDartType()]),
          () => Supertype(_needClass(), [_createDartType(), _createDartType()]),
        ]);
      case NodeKind.SwitchCase:
        // TODO(johnniwinther): Add non-trivial cases.
        return SwitchCase(
          [NullLiteral()],
          [TreeNode.noOffset],
          _createStatement(),
        )..fileOffset = _needFileOffset();
      case NodeKind.NominalParameter:
        return TypeParameter('foo', _createDartType(), _createDartType())
          ..fileOffset = _needFileOffset();
      case NodeKind.StructuralParameter:
        return StructuralParameter('foo', _createDartType(), _createDartType());
      case NodeKind.Typedef:
        return Typedef('foo', _createDartType(), fileUri: _uri)
          ..fileOffset = _needFileOffset();
      case NodeKind.ExtensionTypeDeclaration:
        // TODO(johnniwinther): Add non-trivial cases.
        return ExtensionTypeDeclaration(name: 'foo', fileUri: _uri)
          ..fileOffset = _needFileOffset()
          ..declaredRepresentationType = _createDartType();
      case NodeKind.MapPatternEntry:
        return MapPatternEntry(_createExpression(), _createPattern())
          ..fileOffset = _needFileOffset();
      case NodeKind.MapPatternRestEntry:
        return MapPatternRestEntry()..fileOffset = _needFileOffset();
      case NodeKind.PatternGuard:
        return _createOneOf(_pendingNodes, kind, index, [
          () =>
              new PatternGuard(_createPattern())
                ..fileOffset = _needFileOffset(),
          () =>
              new PatternGuard(_createPattern(), _createExpression())
                ..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.PatternSwitchCase:
        return _createOneOf(_pendingNodes, kind, index, [
          () => new PatternSwitchCase(
            [],
            [],
            _createStatement(),
            isDefault: true,
            hasLabel: false,
            jointVariables: [],
            jointVariableFirstUseOffsets: null,
          ),
          () => new PatternSwitchCase(
            [0],
            [_createNodeFromKind(NodeKind.PatternGuard) as PatternGuard],
            _createStatement(),
            isDefault: false,
            hasLabel: true,
            jointVariables: [],
            jointVariableFirstUseOffsets: null,
          ),
        ]);
      case NodeKind.SwitchExpressionCase:
        return new SwitchExpressionCase(
          _createNodeFromKind(NodeKind.PatternGuard) as PatternGuard,
          _createExpression(),
        )..fileOffset = _needFileOffset();
      case NodeKind.VariableDeclaration:
        return _createOneOf(_pendingNodes, kind, index, [
          () => new VariableDeclaration(
            _createVariableFromKind(VariableKind.LocalVariable)
                as DeclaredVariable,
          ),
          () => new VariableDeclaration(
            _createVariableFromKind(VariableKind.LateVariable)
                as DeclaredVariable,
          ),
        ]);
      case NodeKind.TypeVariable:
        throw new UnimplementedError("Unimplemented support for kind $kind.");
    }
  }

  /// Helper that creates a node of type [V] using the list of [creators].
  ///
  /// The [index] indicates how many nodes of the [kind] that have currently
  /// been created. If there are more [creators] left after having created the
  /// [index]th node, [pending] is updated with the next pending index. If all
  /// pending nodes of the given [kind] have been created, [index] is `null` and
  /// the first [creators] function is used.
  V _createOneOf<K, V>(
    Map<K, int> pending,
    K kind,
    int? index,
    List<V Function()> creators,
  ) {
    if (index == null) {
      // All pending nodes have been created so we just create the first.
      return creators[0]();
    }
    if (index + 1 < creators.length) {
      pending[kind] = index + 1;
    }
    return creators[index]();
  }
}

/// [NodeKind]s for nodes that can occur inside member bodies.
const Set<NodeKind> inBodyNodeKinds = {
  NodeKind.Arguments,
  NodeKind.Catch,
  NodeKind.FunctionNode,
  NodeKind.MapLiteralEntry,
  NodeKind.MapPatternEntry,
  NodeKind.MapPatternRestEntry,
  NodeKind.Name,
  NodeKind.NamedExpression,
  NodeKind.NamedType,
  NodeKind.SwitchCase,
  NodeKind.NominalParameter,
  NodeKind.PatternGuard,
  NodeKind.PatternSwitchCase,
  NodeKind.SwitchExpressionCase,
  NodeKind.VariableDeclaration,
};
