// 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<Variable> _neededVariables = [];
  List<LabeledStatement> _neededLabeledStatements = [];
  List<FunctionDeclaration> _neededFunctionDeclarations = [];
  List<SwitchCase> _neededSwitchCases = [];

  /// Creates a [NodeCreator] requested to create nodes of the specified kinds.
  NodeCreator({
    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, {
         VariableKind.CatchVariable,
         VariableKind.LocalVariable,
         VariableKind.LateVariable,
         VariableKind.PositionalParameter,
         VariableKind.NamedParameter,
         VariableKind.SyntheticVariable,
         VariableKind.ThisVariable,
       }),
       _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 (Variable 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());
    }
    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;
          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.LegacyVariable:
        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 [Variable] node that fits the requirements.
  ///
  /// If no such [Variable] exists in [_neededVariables],
  /// a new [Variable] is created and added to
  /// [_neededVariables].
  // TODO(johnniwinther): Add requirements when/where needed.
  Variable _needVariable() {
    for (Variable variable in _neededVariables) {
      return variable;
    }
    Variable variable = Variable('foo');
    _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(
      Variable('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(_createVariable(), _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, _createVariable())
                ..fileOffset = _needFileOffset(),
          () =>
              VariablePattern(_createDartType(), _createVariable())
                ..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(
            _createVariable(),
            _createExpression(),
            _createStatement(),
            isAsync: false,
          )..fileOffset = _needFileOffset(),
          () => ForInStatement(
            _createVariable(),
            _createExpression(),
            _createStatement(),
            isAsync: true,
          )..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.ForStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () =>
              ForStatement([], null, [], _createStatement())
                ..fileOffset = _needFileOffset(),
          () => ForStatement(
            [VariableDeclaration(_createVariable())],
            _createExpression(),
            [_createExpression()],
            _createStatement(),
          )..fileOffset = _needFileOffset(),
          () => ForStatement(
            [
              VariableDeclaration(_createVariable()),
              VariableDeclaration(_createVariable()),
            ],
            _createExpression(),
            [_createExpression(), _createExpression()],
            _createStatement(),
          )..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.FunctionDeclaration:
        return FunctionDeclaration(
          Variable(null, isSynthesized: true),
          _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(Variable('foo')..fileOffset = _needFileOffset())
              ..fileOffset = _needFileOffset(),
          )..fileOffset = _needFileOffset(),
          () => VariableStatement(
            VariableDeclaration(
              Variable('foo', initializer: _createExpression())
                ..fileOffset = _needFileOffset(),
            )..fileOffset = _needFileOffset(),
          )..fileOffset = _needFileOffset(),
          () => VariableStatement(
            VariableDeclaration(
              Variable('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 _createVariable() {
    return Variable('foo');
  }

  /// 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(_createVariable())
          ..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:
        // TODO(johnniwinther): Add non-trivial cases.
        return Catch(null, _createStatement())..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:
        // TODO(johnniwinther): Add non-trivial cases.
        return FunctionNode(_createStatement())..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 new VariableDeclaration(
          _createNodeFromKind(NodeKind.LegacyVariable) as Variable,
        );
      case NodeKind.LegacyVariable:
        return _createOneOf(_pendingNodes, kind, index, [
          () => Variable('foo')..fileOffset = _needFileOffset(),

          () =>
              Variable('foo', initializer: _createExpression())
                ..fileOffset = _needFileOffset(),
          () =>
              Variable('foo', type: _createDartType())
                ..fileOffset = _needFileOffset(),
        ]);
      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,
};
