// Copyright (c) 2018, 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 'dart:io';
import 'dart:math';

import 'package:args/args.dart';

import 'dartfuzz_api_table.dart';
import 'dartfuzz_ffi_api.dart';
import 'dartfuzz_type_table.dart';

// Version of DartFuzz. Increase this each time changes are made
// to preserve the property that a given version of DartFuzz yields
// the same fuzzed program for a deterministic random seed.
const String version = '1.93';

// Restriction on statements and expressions.
const int stmtDepth = 1;
const int exprDepth = 2;
const int nestDepth = 1;
const int numStatements = 2;
const int numGlobalVars = 4;
const int numLocalVars = 4;
const int numGlobalMethods = 4;
const int numMethodParams = 4;
const int numClasses = 4;
const int numExtensionMethodsPerClass = 3;
const int numDartTypeExtensions = 5;

// Naming conventions.
const varName = 'var';
const paramName = 'par';
const localName = 'loc';
const fieldName = 'fld';
const methodName = 'foo';

/// Enum for the different types of methods generated by the fuzzer.
enum MethodType {
  globalMethod,
  ffiMethod,
  instanceMethod,
  callMethod,
  extensionMethod
}

/// Base class for all methods in the program generated by DartFuzz.
abstract class Method {
  Method(this.name, this.parameters, this.fuzzer)
      : recursionAllowed = fuzzer.coinFlip() {
    if (recursionAllowed) {
      // Add the recursion depth parameter.
      parameters.add(DartType.INT);
    }
  }

  String get recursionDepthParamName => '$paramName${parameters.length - 1}';
  DartType get returnType => parameters[0];

  void emitCallParameters(int depth, bool isRecursiveCall,
      {RhsFilter? rhsFilter}) {
    if (isRecursiveCall && !recursionAllowed) {
      throw StateError('Did not expect a recursive call in $name');
    }
    fuzzer.emitParenWrapped(() => fuzzer.emitCommaSeparated((int i) {
          // If this function can be called recursively, the last parameter is the
          // recursion depth parameter.
          if (i == parameters.length - 1 && recursionAllowed) {
            if (isRecursiveCall) {
              // This is a recursive call, so we increase the recursion depth
              // parameter.
              fuzzer.emit('$recursionDepthParamName + 1');
            } else {
              // This isn't a recursive call. Our recursion depth is 0.
              fuzzer.emit('0');
            }
          } else {
            fuzzer.emitExpr(depth, parameters[i], rhsFilter: rhsFilter);
          }
        }, parameters.length, start: 1));
  }

  void disableRecursionScope(Function callback) {
    final originalState = recursionAllowed;
    recursionAllowed = false;
    callback();
    recursionAllowed = originalState;
  }

  void emitRecursionBaseCase() {
    fuzzer.emitIfStatement(() {
      fuzzer.emit('$recursionDepthParamName >= ');
      fuzzer.emitSmallPositiveInt();
    }, () {
      // Temporarily set recursionAllowed to false so that we don't have a
      // recursive call in the return statement of the base case.
      disableRecursionScope(fuzzer.emitReturn);
      return false;
    });
  }

  void emitFunctionBody() {
    if (!recursionAllowed && fuzzer.rollDice(10)) {
      // Emit a method using "=>" syntax.
      fuzzer.emit(' => ');
      fuzzer.emitExpr(0, returnType, includeSemicolon: true);
    } else {
      fuzzer.emitBraceWrapped(() {
        assert(fuzzer.localVars.isEmpty);
        if (recursionAllowed) {
          emitRecursionBaseCase();
        }
        if (fuzzer.emitStatements(0)) {
          fuzzer.emitReturn();
        }
        assert(fuzzer.localVars.isEmpty);
      });
    }
  }

  void emitFunctionDefinition() {
    final type = returnType.dartName;
    fuzzer.emitLn('$type $name', newline: false);
    fuzzer.emitParenWrapped(() => fuzzer.emitParDecls(parameters));
    emitFunctionBody();
    fuzzer.emitNewline();
    fuzzer.emitNewline();
  }

  String emitCall(int depth,
      {RhsFilter? rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    var outputName = name;
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  // Main emitter for a method.
  void emit() {
    emitFunctionDefinition();
  }

  final String name;
  final List<DartType> parameters;
  final DartFuzz fuzzer;
  bool recursionAllowed;
}

/// Class for global methods generated by DartFuzz.
class GlobalMethod extends Method {
  GlobalMethod(String name, List<DartType> parameters, DartFuzz fuzzer)
      : super(name, parameters, fuzzer);
}

/// Class for ffi methods generated by DartFuzz.
class FfiMethod extends Method {
  FfiMethod(
      String namePrefix, int index, List<DartType> parameters, DartFuzz fuzzer)
      : ffiCastName = '${namePrefix}FfiCast$index',
        super('${namePrefix}Ffi$index', parameters, fuzzer);

  @override
  void emitFunctionBody() {
    fuzzer.emitBraceWrapped(() {
      assert(fuzzer.localVars.isEmpty);
      if (recursionAllowed) {
        emitRecursionBaseCase();
      }
      if (fuzzer.emitStatements(0)) {
        fuzzer.emitReturn();
      }
      assert(fuzzer.localVars.isEmpty);
    });
  }

  @override
  void emit() {
    fuzzer.emitFfiTypedef(this);
    emitFunctionDefinition();
    fuzzer.emitFfiCast('$ffiCastName', '$name', '${name}Type', parameters);
    fuzzer.emitNewline();
    fuzzer.emitNewline();
  }

  final String ffiCastName;
}

/// Class for instance methods generated by DartFuzz.
class InstanceMethod extends Method {
  InstanceMethod(
      String name, List<DartType> parameters, DartFuzz fuzzer, this.className)
      : super(name, parameters, fuzzer);

  @override
  String emitCall(int depth,
      {RhsFilter? rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    var outputName = name;
    if (fuzzer.currentClassIndex == null) {
      // If we're calling an instance method from outside the class, then we
      // should construct an object of that class first.
      outputName = '$className().$name';
    }
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  final String className;
}

class CallMethod extends Method {
  CallMethod(List<DartType> parameters, DartFuzz fuzzer, this.className)
      : super('call', parameters, fuzzer);

  @override
  String emitCall(int depth,
      {RhsFilter? rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    String outputName;
    outputName = '$className()';
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  @override
  void emit() {
    // Override the parent class' call method.
    fuzzer.emit('@override');
    fuzzer.emitNewline();
    emitFunctionDefinition();
  }

  final String className;
}

// Class for extension methods generated by DartFuzz.
class ExtensionMethod extends Method {
  ExtensionMethod(String name, List<DartType> parameters, DartFuzz fuzzer,
      this.className, this.extensionName, this.type)
      : super(name, parameters, fuzzer);
  @override
  String emitCall(
    int depth, {
    RhsFilter? rhsFilter,
    bool includeSemicolon = false,
    bool isRecursiveCall = false,
  }) {
    var outputName = name;

    // If we're calling an extension method on a class from outside the class,
    // we must call it using an object of the class or using explicit extension
    // application. Extension methods on Dart types are presently always called
    // using a variable of the Dart type or using explicit extension
    // application.
    if (fuzzer.currentClassIndex == null || type != null) {
      var invokingObject = type != null
          ? fuzzer.pickScalarVar(type!.toNonNullable())
          : '$className()';

      if (extensionName != null && fuzzer.coinFlip()) {
        outputName = '$extensionName($invokingObject).$name';
      } else {
        outputName = '$invokingObject.$name';
      }
    }
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  final String className;
  final String extensionName;
  final DartType? type;
}

// Class that tracks the state of the filter applied to the
// right-hand-side of an assignment in order to avoid generating
// left-hand-side variables.
class RhsFilter {
  RhsFilter(this._remaining, this.lhsVar);
  static RhsFilter? fromDartType(DartType tp, String lhsVar) {
    if (DartType.isGrowableType(tp)) {
      return RhsFilter(1, lhsVar);
    }
    return null;
  }

  // Clone the current RhsFilter instance and set remaining to 0.
  // This is used for parameter expressions.
  static RhsFilter? cloneEmpty(RhsFilter? rhsFilter) =>
      rhsFilter == null ? null : RhsFilter(0, rhsFilter.lhsVar);
  void consume() => _remaining--;
  bool get shouldFilter => _remaining <= 0;
  // Number of times the lhs variable can still be used on the rhs.
  int _remaining;
  // The name of the lhs variable to be filtered from the rhs.
  final String lhsVar;
}

/// Class that specifies the api for calling library and ffi functions (if
/// enabled).
class DartApi {
  DartApi(bool ffi) : typeToLibraryMethods = DartLib.typeToLibraryMethods {
    if (ffi) {
      typeToLibraryMethods[DartType.INT] = [
        ...[
          DartLib('intComputation',
              [DartType.VOID, ...List<DartType>.filled(4, DartType.INT)], true),
          DartLib('takeMaxUint16', [DartType.VOID, DartType.INT], true),
          DartLib(
              'sumPlus42', [DartType.VOID, DartType.INT, DartType.INT], true),
          DartLib('returnMaxUint8', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMaxUint16', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMaxUint32', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt8', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt16', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt32', [DartType.VOID, DartType.VOID], true),
          DartLib('takeMinInt16', [DartType.VOID, DartType.INT], true),
          DartLib('takeMinInt32', [DartType.VOID, DartType.INT], true),
          DartLib('uintComputation',
              [DartType.VOID, ...List<DartType>.filled(4, DartType.INT)], true),
          DartLib('sumSmallNumbers',
              [DartType.VOID, ...List<DartType>.filled(6, DartType.INT)], true),
          DartLib('takeMinInt8', [DartType.VOID, DartType.INT], true),
          DartLib('takeMaxUint32', [DartType.VOID, DartType.INT], true),
          DartLib('takeMaxUint8', [DartType.VOID, DartType.INT], true),
          DartLib('minInt64', [DartType.VOID, DartType.VOID], true),
          DartLib('minInt32', [DartType.VOID, DartType.VOID], true),
          // Use small int to avoid overflow divergences due to size
          // differences in intptr_t on 32-bit and 64-bit platforms.
          DartLib('sumManyIntsOdd',
              [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(11, Restriction.small)
              ]),
          DartLib('sumManyInts',
              [DartType.VOID, ...List<DartType>.filled(10, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(10, Restriction.small)
              ]),
          DartLib('regress37069',
              [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(11, Restriction.small)
              ]),
        ],
        ...DartLib.intLibs,
      ];

      typeToLibraryMethods[DartType.DOUBLE] = [
        if (ffi) ...[
          DartLib('times1_337Float', [DartType.VOID, DartType.DOUBLE], true),
          DartLib(
              'sumManyDoubles',
              [DartType.VOID, ...List<DartType>.filled(10, DartType.DOUBLE)],
              true),
          DartLib('times1_337Double', [DartType.VOID, DartType.DOUBLE], true),
          DartLib(
              'sumManyNumbers',
              [
                DartType.VOID,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE
              ],
              true),
          DartLib('inventFloatValue', [DartType.VOID, DartType.VOID], true),
          DartLib('smallDouble', [DartType.VOID, DartType.VOID], true),
        ],
        ...DartLib.doubleLibs,
      ];
    }
  }

  final typeToLibraryMethods;
}

/// Class that generates a random, but runnable Dart program for fuzz testing.
class DartFuzz {
  DartFuzz(this.seed, this.fp, this.ffi, this.flatTp, this.file,
      {this.minimize = false, this.smask, this.emask});

  void run() {
    // Initialize program variables.
    rand = Random(seed);
    currentClassIndex = null;
    currentMethod = null;
    currentMethodIndex = null;
    // Setup Dart types.
    dartType = DartType.fromDartConfig(enableFp: fp, disableNesting: flatTp);
    // Setup minimization parameters.
    initMinimization();
    // Setup the library and ffi api.
    api = DartApi(ffi);
    // Setup the types.
    localVars = <DartType?>[];
    iterVars = <String>[];
    globalVars = fillTypes1(limit: numGlobalVars);
    globalVars.addAll(dartType.allTypes);
    globalMethods = getMethods(
        numGlobalMethods, numMethodParams, MethodType.globalMethod,
        namePrefix: methodName);
    classFields = fillTypes2(limit2: numClasses, limit1: numLocalVars);
    final numClassMethods = 1 + numClasses - classFields.length;
    classMethods = getClassMethods(classFields.length, numClassMethods,
        numMethodParams, fillTypes1(limit: numMethodParams));
    virtualClassMethods = <Map<int, List<int>>>[];
    classParents = <int>[];
    // Setup optional ffi methods and types.
    if (ffi) {
      globalMethods.addAll(getMethods(
          numGlobalMethods, numMethodParams, MethodType.ffiMethod,
          namePrefix: methodName));
    }
    // Generate.
    emitHeader();
    emitVariableDeclarations(varName, globalVars);
    emitMethods(globalMethods);
    for (var i = 0; i < numDartTypeExtensions; ++i) {
      var type = oneOfSet(dartType.allTypes);
      emitAndAddExtensionMethods(globalMethods, type.name, '${methodName}E$i',
          '$methodName${i}_Extension',
          type: type);
    }
    emitClasses();
    emitMain();
    // Sanity.
    assert(currentClassIndex == null);
    assert(currentMethod == null);
    assert(currentMethodIndex == null);
    assert(indent == 0);
    assert(nest == 0);
    assert(localVars.isEmpty);
  }

  List<Method> getMethods(int maxMethods, int maxParams, MethodType methodType,
      {String? className,
      String? extensionName,
      String? namePrefix,
      DartType? type}) {
    final list = <Method>[];
    for (var i = 0, n = chooseOneUpTo(maxMethods); i < n; i++) {
      final params = fillTypes1(
          limit: maxParams, isFfi: methodType == MethodType.ffiMethod);
      switch (methodType) {
        case MethodType.globalMethod:
          list.add(GlobalMethod('$namePrefix$i', params, this));
          break;
        case MethodType.ffiMethod:
          list.add(FfiMethod(namePrefix!, i, params, this));
          break;
        case MethodType.instanceMethod:
          list.add(InstanceMethod('$namePrefix$i', params, this, className!));
          break;
        case MethodType.extensionMethod:
          list.add(ExtensionMethod(
              '$namePrefix$i', params, this, className!, extensionName!, type));
          break;
        default:
          break;
      }
    }
    return list;
  }

  List<List<Method>> getClassMethods(int numClasses, int maxMethods,
      int maxParams, List<DartType> callMethodParams) {
    final methodsForAllClasses = <List<Method>>[];
    for (var i = 0; i < numClasses; i++) {
      final methodsForCurrentClass = getMethods(
          maxMethods, maxParams, MethodType.instanceMethod,
          className: 'X$i', namePrefix: '$methodName${i}_');
      // Add the call method for the current class. The prototype for the call
      // method is pre-decided. This is because we are possibly overriding the
      // parent class' call method, in which case the prototype should be the
      // same. To simplify the dartfuzz logic, all call methods have the same
      // prototype.
      methodsForCurrentClass.add(CallMethod(callMethodParams, this, 'X$i'));
      methodsForAllClasses.add(methodsForCurrentClass);
    }
    return methodsForAllClasses;
  }

  //
  // General Helpers.
  //

  BigInt genMask(int m) => BigInt.from(1) << m;
  int choose(int c) => rand.nextInt(c);
  int chooseOneUpTo(int c) => choose(c) + 1;
  bool coinFlip() => rand.nextBool();
  bool rollDice(int c) => (choose(c) == 0);
  double uniform() => rand.nextDouble();

  // Picks one of the given choices.
  T oneOf<T>(List<T> choices) => choices[choose(choices.length)];
  T oneOfSet<T>(Set<T> choices) => choices.elementAt(choose(choices.length));

  //
  // Code Structure Helpers.
  //

  void incIndent() => indent += 2;
  void decIndent() => indent -= 2;

  void emitZero() => emit('0');

  void emitTryCatchFinally(Function tryBody, Function catchBody,
      {Function? finallyBody}) {
    emitLn('try ', newline: false);
    emitBraceWrapped(() => tryBody());
    emit(' on OutOfMemoryError ');
    emitBraceWrapped(() => emitLn('exit($oomExitCode);', newline: false));
    emit(' on StackOverflowError ');
    emitBraceWrapped(() => emitLn('exit($oomExitCode);', newline: false));
    emit(' catch (e, st) ');
    emitBraceWrapped(catchBody);
    if (finallyBody != null) {
      emit(' finally ');
      emitBraceWrapped(finallyBody);
    }
  }

  dynamic emitWrapped(List<String> pair, Function exprEmitter,
      {bool shouldIndent = true}) {
    assert(pair.length == 2);
    emit(pair[0]);
    if (shouldIndent) {
      incIndent();
      emitNewline();
    }
    final result = exprEmitter();
    if (shouldIndent) {
      decIndent();
      emitNewline();
      emitLn(pair[1], newline: false);
    } else {
      emit(pair[1]);
    }
    return result;
  }

  dynamic emitParenWrapped(Function exprEmitter,
      {bool includeSemicolon = false}) {
    final result =
        emitWrapped(const ['(', ')'], exprEmitter, shouldIndent: false);
    if (includeSemicolon) {
      emit(';');
    }
    return result;
  }

  dynamic emitBraceWrapped(Function exprEmitter, {bool shouldIndent = true}) =>
      emitWrapped(const ['{', '}'], exprEmitter, shouldIndent: shouldIndent);

  dynamic emitSquareBraceWrapped(Function exprEmitter) =>
      emitWrapped(const ['[', ']'], exprEmitter, shouldIndent: false);

  dynamic emitCommaSeparated(Function(int) elementBuilder, int length,
      {int start = 0, bool newline = false}) {
    for (var i = start; i < length; ++i) {
      elementBuilder(i);
      if (i + 1 != length) {
        emit(',', newline: newline);
        if (!newline) {
          emit(' ');
        }
      }
    }
  }

  void emitFunctionDefinition(String name, Function body, {String? retType}) {
    emitIndentation();
    if (retType != null) {
      emit(retType + ' ');
    }
    emit(name);
    emit('() '); // TODO(bkonyi): handle params

    emitBraceWrapped(body);
  }

  bool emitIfStatement(
      Function ifConditionEmitter, bool Function() ifBodyEmitter,
      {bool Function()? elseBodyEmitter}) {
    emitLn('if ', newline: false);
    emitParenWrapped(ifConditionEmitter);
    emit(' ');
    final bool ifMayFallThrough = emitBraceWrapped(ifBodyEmitter);
    var elseMayFallThrough = true;
    if (elseBodyEmitter != null) {
      emit(' else ');
      elseMayFallThrough = emitBraceWrapped(elseBodyEmitter);
    }
    return ifMayFallThrough || elseMayFallThrough;
  }

  void emitImport(String library, {String? asName}) => (asName == null)
      ? emitLn("import '$library';")
      : emitLn("import '$library' as $asName;");

  void emitBinaryComparison(Function e1, String op, Function e2,
      {bool includeSemicolon = false}) {
    e1();
    emit(' $op ');
    e2();
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Randomly specialize interface if possible. E.g. num to int.
  DartType maybeSpecializeInterface(DartType tp) {
    if (!dartType.isSpecializable(tp)) return tp;
    var resolvedTp = oneOfSet(dartType.interfaces(tp));
    return resolvedTp;
  }

  //
  // Minimization components.
  //

  void initMinimization() {
    stmtCntr = 0;
    exprCntr = 0;
    skipStmt = false;
    skipExpr = false;
  }

  void emitMinimizedLiteral(DartType tp) {
    switch (tp) {
      case DartType.BOOL:
        emit('true');
        break;
      case DartType.INT:
        emit('1');
        break;
      case DartType.DOUBLE:
        emit('1.0');
        break;
      case DartType.STRING:
        emit('"a"');
        break;
      case DartType.LIST_INT:
        emit('[1]');
        break;
      case DartType.SET_INT:
        emit('{1}');
        break;
      case DartType.MAP_INT_STRING:
        emit('{1: "a"}');
        break;
      default:
        throw 'Unknown DartType $tp';
    }
  }

  // Process the opening of a statement.
  // Determine whether the statement should be skipped based on the
  // statement index stored in stmtCntr and the statement mask stored
  // in smask.
  // Returns true if the statement should be skipped.
  bool processStmtOpen() {
    // Do nothing if we are not in minimization mode.
    if (!minimize) {
      return false;
    }
    // Check whether the bit for the current statement number is set in the
    // statement bitmap. If so skip this statement.
    final newMask = genMask(stmtCntr);
    final maskBitSet = (smask! & newMask) != BigInt.zero;
    // Statements are nested, therefore masking one statement like e.g.
    // a for loop leads to other statements being omitted.
    // Here we update the statement mask to include the additionally
    // omitted statements.
    if (skipStmt) {
      smask = smask! | newMask;
    }
    // Increase the statement counter.
    stmtCntr++;
    if (!skipStmt && maskBitSet) {
      skipStmt = true;
      return true;
    }
    return false;
  }

  // Process the closing of a statement.
  // The variable resetSkipStmt indicates whether this
  // statement closes the sequence of skipped statement.
  // E.g. the end of a loop where all contained statements
  // were skipped.
  void processStmtClose(bool resetSkipStmt) {
    if (!minimize) {
      return;
    }
    if (resetSkipStmt) {
      skipStmt = false;
    }
  }

  // Process the opening of an expression.
  // Determine whether the expression should be skipped based on the
  // expression index stored in exprCntr and the expression mask stored
  // in emask.
  // Returns true is the expression is skipped.
  bool processExprOpen(DartType tp) {
    // Do nothing if we are not in minimization mode.
    if (!minimize) {
      return false;
    }
    // Check whether the bit for the current expression number is set in the
    // expression bitmap. If so skip this expression.
    final newMask = genMask(exprCntr);
    final maskBitSet = (emask! & newMask) != BigInt.zero;
    // Expressions are nested, therefore masking one expression like e.g.
    // a for loop leads to other expressions being omitted.
    // Similarly, if the whole statement is skipped, all the expressions
    // within that statement are implicitly masked.
    // Here we update the expression mask to include the additionally
    // omitted expressions.
    if (skipExpr || skipStmt) {
      emask = emask! | newMask;
    }
    exprCntr++;
    if (skipStmt) {
      return false;
    }
    if (!skipExpr && maskBitSet) {
      emitMinimizedLiteral(tp);
      skipExpr = true;
      return true;
    }
    return false;
  }

  void processExprClose(bool resetExprStmt) {
    if (!minimize || skipStmt) {
      return;
    }
    if (resetExprStmt) {
      skipExpr = false;
    }
  }

  //
  // Program components.
  //

  void emitHeader() {
    emitLn('// The Dart Project Fuzz Tester ($version).');
    emitLn('// Program generated as:');
    emitLn('//   dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp '
        '--${ffi ? "" : "no-"}ffi --${flatTp ? "" : "no-"}flat');
    emitLn('// @dart=2.14');
    emitNewline();
    emitImport('dart:async');
    emitImport('dart:cli');
    emitImport('dart:collection');
    emitImport('dart:convert');
    emitImport('dart:core');
    emitImport('dart:io');
    emitImport('dart:isolate');
    emitImport('dart:math');
    emitImport('dart:typed_data');
    if (ffi) {
      emitImport('dart:ffi', asName: 'ffi');
      emitLn(DartFuzzFfiApi.ffiapi);
    }
    emitNewline();
  }

  void emitFfiCast(String dartFuncName, String ffiFuncName, String typeName,
      List<DartType> pars) {
    emit('${pars[0].name} Function');
    emitParenWrapped(() => emitCommaSeparated(
        (int i) => emit('${pars[i].name}'), pars.length,
        start: 1));
    emit(' $dartFuncName = ffi.Pointer.fromFunction<$typeName>');
    emitParenWrapped(() {
      emit('$ffiFuncName, ');
      emitLiteral(0, pars[0], smallPositiveValue: true);
    });
    emit('.cast<ffi.NativeFunction<$typeName>>().asFunction();');
    emitNewline();
  }

  void emitMethods(List<Method> methods) {
    for (var i = 0; i < methods.length; i++) {
      currentMethod = methods[i];
      currentMethodIndex = i;
      currentMethod!.emit();
      currentMethod = null;
      currentMethodIndex = null;
    }
  }

  // Randomly overwrite some methods from the parent classes.
  void emitVirtualMethods() {
    final currentClassTmp = currentClassIndex;
    var parentClass = classParents[currentClassIndex!];
    final vcm = <int, List<int>>{};
    // Chase randomly up in class hierarchy.
    while (parentClass >= 0) {
      vcm[parentClass] = <int>[];
      for (var j = 0, n = classMethods[parentClass].length; j < n; j++) {
        // Call methods are presently always already overridden, so we
        // shouldn't override them here.
        if (rollDice(8) && !(classMethods[parentClass][j] is CallMethod)) {
          currentClassIndex = parentClass;
          currentMethod = classMethods[parentClass][j];
          currentMethodIndex = j;
          classMethods[parentClass][j].emit();
          vcm[parentClass]!.add(currentMethodIndex!);
          currentClassIndex = null;
          currentMethod = null;
          currentMethodIndex = null;
        }
      }
      if (coinFlip() || classParents.length > parentClass) {
        break;
      } else {
        parentClass = classParents[parentClass];
      }
    }
    currentClassIndex = currentClassTmp;
    virtualClassMethods.add(vcm);
  }

  void emitClasses() {
    assert(classFields.length == classMethods.length);
    for (var i = 0; i < classFields.length; i++) {
      if (i == 0) {
        classParents.add(-1);
        emit('class X0 ');
      } else {
        final parentClass = choose(i);
        classParents.add(parentClass);
        if (coinFlip()) {
          // Inheritance
          emit('class X$i extends X$parentClass ');
        } else {
          // Mixin
          if (classParents[parentClass] >= 0) {
            emit(
                'class X$i extends X${classParents[parentClass]} with X$parentClass ');
          } else {
            emit('class X$i with X$parentClass ');
          }
        }
      }
      emitBraceWrapped(() {
        emitVariableDeclarations('$fieldName${i}_', classFields[i]);
        currentClassIndex = i;
        emitVirtualMethods();
        emitMethods(classMethods[currentClassIndex!]);
        emitFunctionDefinition('run', () {
          if (i > 0) {
            // FIXME(bkonyi): fix potential issue where we try to apply a class
            // as a mixin when it calls super.
            emitLn('super.run();');
          }
          assert(localVars.isEmpty);
          emitStatements(0);
          assert(localVars.isEmpty);
        }, retType: 'void');
      });
      emitNewline();
      emitNewline();
      emitAndAddExtensionMethods(
          classMethods[currentClassIndex!],
          'X$currentClassIndex',
          'XE$currentClassIndex',
          '$methodName${currentClassIndex}_Extension');
      currentClassIndex = null;
    }
  }

  void emitAndAddExtensionMethods(
      List<Method> methodList, className, extensionName, namePrefix,
      {DartType? type}) {
    var endIndex = methodList.length;
    methodList.addAll(getMethods(numExtensionMethodsPerClass, numMethodParams,
        MethodType.extensionMethod,
        className: className,
        // Randomly select between named and anonymous extensions.
        extensionName: coinFlip() ? extensionName : '',
        namePrefix: namePrefix,
        type: type));
    emit('extension $extensionName on $className ');
    emitBraceWrapped(() {
      // Emit the newly added methods.
      for (var i = endIndex; i < methodList.length; i++) {
        currentMethod = methodList[i];
        currentMethodIndex = i;
        methodList[i].emit();
        currentMethod = null;
        currentMethodIndex = null;
      }
    });
    emitNewline();
    emitNewline();
  }

  void emitLoadFfiLib() {
    if (ffi) {
      emitLn('// The following throws an uncaught exception if the ffi library '
          'is not found.');
      emitLn('// By not catching this exception, we terminate the program with '
          'a full stack trace');
      emitLn('// which, in turn, flags the problem prominently');
      emitIfStatement(() => emit('ffiTestFunctions == null'),
          () => emitPrint('Did not load ffi test functions'));
      emitNewline();
    }
  }

  void emitMain() => emitFunctionDefinition('main', () {
        emitLoadFfiLib();

        // Call each global method once.
        for (var i = 0; i < globalMethods.length; i++) {
          late String outputName;
          emitTryCatchFinally(
              () => outputName =
                  globalMethods[i].emitCall(1, includeSemicolon: true),
              () => emitPrint('${outputName}() throws'));
          emitNewline();
        }

        // Call each class method once.
        for (var i = 0; i < classMethods.length; i++) {
          for (var j = 0; j < classMethods[i].length; j++) {
            late String outputName;
            emitNewline();
            emitTryCatchFinally(
                () => outputName =
                    classMethods[i][j].emitCall(1, includeSemicolon: true),
                () => emitPrint('$outputName throws'));
          }
          // Call each virtual class method once.
          var parentClass = classParents[i];
          while (parentClass >= 0) {
            if (virtualClassMethods[i].containsKey(parentClass)) {
              for (var j = 0;
                  j < virtualClassMethods[i][parentClass]!.length;
                  j++) {
                late String outputName;
                emitNewline();
                emitTryCatchFinally(
                    () => outputName = classMethods[parentClass][j]
                        .emitCall(1, includeSemicolon: true),
                    () => emitPrint('$outputName throws'));
              }
            }
            parentClass = classParents[parentClass];
          }
        }

        emitNewline();
        emitTryCatchFinally(() {
          emitLn('X${classFields.length - 1}().run();', newline: false);
        }, () {
          emitPrint('X${classFields.length - 1}().run() throws');
        });

        emitNewline();
        emitTryCatchFinally(() {
          for (var i = 0; i < globalVars.length; i++) {
            emitPrint('$varName$i: \$$varName$i');
            emitNewline();
          }
        }, () => emitPrint('print() throws'));
      });

  //
  // Declarations.
  //

  void emitVariableDeclarations(String name, List<DartType> vars) {
    for (var i = 0; i < vars.length; i++) {
      var tp = vars[i];
      final varName = '$name$i';
      emitVariableDeclaration(varName, tp,
          initializerEmitter: () => emitConstructorOrLiteral(0, tp));
    }
    emitNewline();
  }

  void emitVariableDeclaration(String name, DartType tp,
      {Function? initializerEmitter,
      bool indent = true,
      bool newline = true,
      bool includeSemicolon = true}) {
    final typeName = tp.dartName;
    if (indent) {
      emitIndentation();
    }
    emit('$typeName $name', newline: false);
    if (initializerEmitter != null) {
      emit(' = ');
      initializerEmitter();
    }
    if (includeSemicolon) {
      emit(';', newline: newline);
    }
  }

  void emitParDecls(List<DartType> pars) => emitCommaSeparated((int i) {
        var tp = pars[i];
        emit('${tp.dartName} $paramName$i');
      }, pars.length, start: 1);

  //
  // Comments (for FE and analysis tools).
  //

  void emitComment() {
    switch (choose(4)) {
      case 0:
        emitLn('// Single-line comment.');
        break;
      case 1:
        emitLn('/// Single-line documentation comment.');
        break;
      case 2:
        emitLn('/*');
        emitLn(' * Multi-line');
        emitLn(' * comment.');
        emitLn(' */');
        break;
      default:
        emitLn('/**');
        emitLn(' ** Multi-line');
        emitLn(' ** documentation comment.');
        emitLn(' */');
        break;
    }
  }

  //
  // Statements.
  //

  // Emit an assignment statement.
  bool emitAssign() {
    final tp = oneOfSet(dartType.allTypes);
    String assignOp;
    if (DartType.isGrowableType(tp)) {
      // Assignments like *= and += on growable types (String, List, ...)
      // may lead to OOM, especially within loops.
      // TODO: Implement a more specific heuristic that selectively allows
      // modifying assignment operators (like += *=) for growable types.
      assignOp = '=';
    } else {
      // Select one of the assign operations for the given type.
      var assignOps = dartType.assignOps(tp);
      if (assignOps.isEmpty) {
        throw 'No assign operation for $tp';
      }
      assignOp = oneOfSet(assignOps);
    }
    emitIndentation();
    // Emit a variable of the lhs type.
    final emittedVar = emitVar(0, tp, isLhs: true, assignOp: assignOp)!;
    var rhsFilter = RhsFilter.fromDartType(tp, emittedVar);
    emit(' $assignOp ');
    // Select one of the possible rhs types for the given lhs type and assign
    // operation.
    var rhsTypes = dartType.assignOpRhs(tp, assignOp);
    if (rhsTypes.isEmpty) {
      throw 'No rhs type for assign $tp $assignOp';
    }
    var rhsType = oneOfSet(rhsTypes);
    emitExpr(0, rhsType, rhsFilter: rhsFilter, includeSemicolon: true);
    return true;
  }

  // Emit a print statement.
  bool emitPrint([String? body]) {
    emitLn('print', newline: false);
    emitParenWrapped(() {
      if (body != null) {
        emit("'$body'");
      } else {
        var tp = oneOfSet(dartType.allTypes);
        emitExpr(0, tp);
      }
    }, includeSemicolon: true);
    return true;
  }

  // Emit a return statement.
  bool emitReturn() {
    var proto = getCurrentProto();
    if (proto == null || proto[0] == DartType.VOID) {
      emitLn('return;');
    } else {
      emitLn('return ', newline: false);
      emitExpr(0, proto[0], includeSemicolon: true);
    }
    return false;
  }

  // Emit a throw statement.
  bool emitThrow() {
    var tp;
    do {
      tp = oneOfSet(dartType.allTypes).toNonNullable();
    } while (tp == DartType.NULL);
    emitLn('throw ', newline: false);
    emitExpr(0, tp, includeSemicolon: true);
    return false;
  }

  // Emit a one-way if statement.
  bool emitIf1(int depth) => emitIfStatement(
      () => emitExpr(0, DartType.BOOL), () => emitStatements(depth + 1));

  // Emit a two-way if statement.
  bool emitIf2(int depth) => emitIfStatement(
      () => emitExpr(0, DartType.BOOL), () => emitStatements(depth + 1),
      elseBodyEmitter: () => emitStatements(depth + 1));

  // Emit a simple increasing for-loop.
  bool emitFor(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final i = localVars.length;
    emitLn('for ', newline: false);
    emitParenWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT,
          initializerEmitter: emitZero, newline: false, indent: false);
      emitBinaryComparison(() => emit(name), '<', emitSmallPositiveInt,
          includeSemicolon: true);
      emit('$name++');
    });
    emitBraceWrapped(() {
      nest++;
      iterVars.add('$localName$i');
      localVars.add(DartType.INT);
      emitStatements(depth + 1);
      localVars.removeLast();
      iterVars.removeLast();
      nest--;
    });
    return true;
  }

  // Emit a simple membership for-in-loop.
  bool emitForIn(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final i = localVars.length;
    // Select one iterable type to be used in 'for in' statement.
    final iterType = oneOfSet(dartType.iterableTypes1);
    // Get the element type contained within the iterable type.
    final elementType = dartType.elementType(iterType);
    if (elementType == null) {
      throw 'No element type for iteration type ${iterType.name}';
    }
    emitLn('for ', newline: false);
    emitParenWrapped(() {
      emit('${elementType.dartName} $localName$i in ');
      localVars.add(null); // declared, but don't use
      emitExpr(0, iterType.toNonNullable());
      localVars.removeLast(); // will get type
    });
    emitBraceWrapped(() {
      nest++;
      localVars.add(elementType);
      emitStatements(depth + 1);
      localVars.removeLast();
      nest--;
    });
    return true;
  }

  // Emit a simple membership forEach loop.
  bool emitForEach(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    emitIndentation();

    // Select one map type to be used in forEach loop.
    final mapType = oneOfSet(dartType.mapTypes);
    final emittedVar = emitScalarVar(mapType.toNonNullable(), isLhs: false);
    iterVars.add(emittedVar);
    emit('.forEach');
    final i = localVars.length;
    final j = i + 1;
    emitParenWrapped(() {
      emitParenWrapped(() => emit('$localName$i, $localName$j'));
      emitBraceWrapped(() {
        // Reset, since forEach cannot break out of own or enclosing context.
        final nestTmp = nest;
        nest = 0;
        // Reset, since return type of forEach is void.
        final currentMethodIndexTemp = currentMethodIndex;
        currentMethodIndex = null;

        // Get the type of the map key and add it to the local variables.
        localVars.add(dartType.indexType(mapType));
        // Get the type of the map values and add it to the local variables.
        localVars.add(dartType.elementType(mapType));
        emitStatements(depth + 1);
        localVars.removeLast();
        localVars.removeLast();

        currentMethodIndex = currentMethodIndexTemp;
        nest = nestTmp;
      });
    }, includeSemicolon: true);
    return true;
  }

  // Emit a while-loop.
  bool emitWhile(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final i = localVars.length;
    emitIndentation();
    emitBraceWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT,
          initializerEmitter: () => emitSmallPositiveInt());
      emitLn('while ', newline: false);
      emitParenWrapped(
          () => emitBinaryComparison(() => emit('--$name'), '>', emitZero));
      emitBraceWrapped(() {
        nest++;
        iterVars.add(name);
        localVars.add(DartType.INT);
        emitStatements(depth + 1);
        localVars.removeLast();
        iterVars.removeLast();
        nest--;
      });
    });
    return true;
  }

  // Emit a do-while-loop.
  bool emitDoWhile(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final i = localVars.length;
    emitIndentation();
    emitBraceWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT, initializerEmitter: emitZero);
      emitLn('do ', newline: false);
      emitBraceWrapped(() {
        nest++;
        iterVars.add(name);
        localVars.add(DartType.INT);
        emitStatements(depth + 1);
        localVars.removeLast();
        iterVars.removeLast();
        nest--;
      });
      emit(' while ');
      emitParenWrapped(
          () => emitBinaryComparison(
              () => emit('++$name'), '<', emitSmallPositiveInt),
          includeSemicolon: true);
    });
    emitNewline();
    return true;
  }

  // Emit a break/continue when inside iteration.
  bool emitBreakOrContinue(int depth) {
    if (nest > 0) {
      switch (choose(2)) {
        case 0:
          emitLn('continue;');
          return false;
        default:
          emitLn('break;');
          return false;
      }
    }
    return emitAssign(); // resort to assignment
  }

  // Emit a switch statement.
  bool emitSwitch(int depth) {
    void emitCase(Function bodyEmitter, {int? kase}) {
      if (kase == null) {
        emitLn('default: ', newline: false);
      } else {
        emitLn('case $kase: ', newline: false);
      }
      emitBraceWrapped(() {
        bodyEmitter();
        emitNewline();
        emitLn('break;',
            newline: false); // always generate, avoid FE complaints
      });
    }

    emitLn('switch ', newline: false);
    emitParenWrapped(() => emitExpr(0, DartType.INT));
    emitBraceWrapped(() {
      var start = choose(1 << 32);
      var step = chooseOneUpTo(10);
      final maxCases = 3;
      for (var i = 0; i < maxCases; i++, start += step) {
        emitCase(() => emitStatement(depth + 1),
            kase: (i == 2 && coinFlip()) ? null : start);
        if (i + 1 != maxCases) {
          emitNewline();
        }
      }
    });
    return true;
  }

  // Emit a new program scope that introduces a new local variable.
  bool emitScope(int depth) {
    emitIndentation();
    emitBraceWrapped(() {
      var tp = oneOfSet(dartType.allTypes);
      final i = localVars.length;
      final name = '$localName$i';
      emitVariableDeclaration(name, tp, initializerEmitter: () {
        localVars.add(null); // declared, but don't use
        emitExpr(0, tp);
        localVars.removeLast(); // will get type
      });
      localVars.add(tp);
      emitStatements(depth + 1);
      localVars.removeLast();
    });
    return true;
  }

  // Emit try/catch/finally.
  bool emitTryCatch(int depth) {
    final emitStatementsClosure = () => emitStatements(depth + 1);
    emitLn('try ', newline: false);
    emitBraceWrapped(emitStatementsClosure);
    emit(' on OutOfMemoryError ');
    emitBraceWrapped(() => emitLn('exit($oomExitCode);', newline: false));
    emit(' on StackOverflowError ');
    emitBraceWrapped(() => emitLn('exit($oomExitCode);', newline: false));
    emit(' catch (exception, stackTrace) ', newline: false);
    emitBraceWrapped(emitStatementsClosure);
    if (coinFlip()) {
      emit(' finally ', newline: false);
      emitBraceWrapped(emitStatementsClosure);
    }
    return true;
  }

  // Emit a single statement.
  bool emitSingleStatement(int depth) {
    // Throw in a comment every once in a while.
    if (rollDice(10)) {
      emitComment();
    }
    // Continuing nested statements becomes less likely as the depth grows.
    if (choose(depth + 1) > stmtDepth) {
      return emitAssign();
    }
    // Possibly nested statement.
    switch (choose(17)) {
      // Favors assignment.
      case 0:
        return emitPrint();
      case 1:
        return emitReturn();
      case 2:
        return emitThrow();
      case 3:
        return emitIf1(depth);
      case 4:
        return emitIf2(depth);
      case 5:
        return emitFor(depth);
      case 6:
        return emitForIn(depth);
      case 7:
        return emitWhile(depth);
      case 8:
        return emitDoWhile(depth);
      case 9:
        return emitBreakOrContinue(depth);
      case 10:
        return emitSwitch(depth);
      case 11:
        return emitScope(depth);
      case 12:
        return emitTryCatch(depth);
      case 13:
        return emitForEach(depth);
      case 14:
        emitLibraryCall(depth, DartType.VOID, includeSemicolon: true);
        return true;
      default:
        return emitAssign();
    }
  }

  // Emit a statement (main entry).
  // Returns true if code *may* fall-through
  // (not made too advanced to avoid FE complaints).
  bool emitStatement(int depth) {
    final resetSkipStmt = processStmtOpen();
    var ret = emitSingleStatement(depth);
    processStmtClose(resetSkipStmt);
    return ret;
  }

  // Emit statements. Returns true if code may fall-through.
  bool emitStatements(int depth) {
    var s = chooseOneUpTo(numStatements);
    for (var i = 0; i < s; i++) {
      if (!emitStatement(depth)) {
        return false; // rest would be dead code
      }
      if (i + 1 != s) {
        emitNewline();
      }
    }
    return true;
  }

  //
  // Expressions.
  //

  void emitBool() => emit(coinFlip() ? 'true' : 'false');

  void emitNull() => emit('null');

  void emitSmallPositiveInt({int limit = 50, bool includeSemicolon = false}) {
    emit('${choose(limit)}');
    if (includeSemicolon) {
      emit(';');
    }
  }

  void emitSmallNegativeInt() => emit('-${choose(100)}');

  void emitInt() {
    switch (choose(7)) {
      // Favors small ints.
      case 0:
      case 1:
      case 2:
        emitSmallPositiveInt();
        break;
      case 3:
      case 4:
      case 5:
        emitSmallNegativeInt();
        break;
      default:
        emit('${oneOf(interestingIntegers)}');
        break;
    }
  }

  void emitDouble() => emit('${uniform()}');

  void emitNum({bool smallPositiveValue = false}) {
    if (!fp || coinFlip()) {
      if (smallPositiveValue) {
        emitSmallPositiveInt();
      } else {
        emitInt();
      }
    } else {
      emitDouble();
    }
  }

  void emitChar() {
    switch (choose(10)) {
      // Favors regular char.
      case 0:
        emit(oneOf(interestingChars));
        break;
      default:
        emit(regularChars[choose(regularChars.length)]);
        break;
    }
  }

  void emitString({int length = 8}) {
    final n = choose(length);
    emit("'");
    for (var i = 0; i < n; i++) {
      emitChar();
    }
    emit("'");
  }

  void emitElementExpr(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool isConst = false}) {
    // Inside a constant collection, keep collection elements constants too.
    if (isConst) {
      if (DartType.isCollectionType(tp)) {
        emitConstCollection(depth + 1, tp, rhsFilter: rhsFilter);
        return;
      }
    }
    // Use literals outside a class or inside a constant collection.
    if (currentMethodIndex == null || isConst) {
      emitLiteral(depth, tp, rhsFilter: rhsFilter);
    } else {
      emitExpr(depth, tp, rhsFilter: rhsFilter);
    }
  }

  void emitElement(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool isConst = false}) {
    // Get the element type contained in type tp.
    // E.g. element type of List<String> is String.
    final elementType = dartType.elementType(tp);
    // Decide whether we need to generate Map or List/Set type elements.
    if (DartType.isMapType(tp)) {
      // Emit construct for the map key type.
      final indexType = dartType.indexType(tp);
      emitIndentation();
      emitElementExpr(depth, indexType, rhsFilter: rhsFilter, isConst: isConst);
      emit(' : ');
      // Emit construct for the map value type.
      emitElementExpr(depth, elementType,
          rhsFilter: rhsFilter, isConst: isConst);
    } else {
      // List and Set types.
      emitElementExpr(depth, elementType,
          rhsFilter: rhsFilter, isConst: isConst);
    }
  }

  void emitCollectionElement(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    var r = (depth <= exprDepth) ? choose(10) : 10;
    // TODO (felih): disable complex collection constructs for new types for
    // now.
    if (!{DartType.MAP_INT_STRING, DartType.LIST_INT, DartType.SET_INT}
        .contains(tp)) {
      emitElement(depth, tp, rhsFilter: rhsFilter);
      return;
    }
    switch (r) {
      // Favors elements over control-flow collections.
      case 0:
        emitLn('...', newline: false); // spread
        emitCollection(depth + 1, tp, rhsFilter: rhsFilter);
        break;
      case 1:
        emitLn('if ', newline: false);
        emitParenWrapped(() =>
            emitElementExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter));
        emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
        if (coinFlip()) {
          emitNewline();
          emitLn('else ', newline: false);
          emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
        }
        break;
      case 2:
        {
          final i = localVars.length;
          // TODO (felih): update to use new type system. Add types like
          // LIST_STRING etc.
          emitLn('for ', newline: false);
          emitParenWrapped(() {
            final local = '$localName$i';
            iterVars.add(local);
            // For-loop (induction, list, set).
            localVars.add(null); // declared, but don't use
            switch (choose(3)) {
              case 0:
                emitVariableDeclaration(local, DartType.INT,
                    initializerEmitter: emitZero, indent: false);
                emitBinaryComparison(() => emit(local), '<',
                    () => emitSmallPositiveInt(limit: 16),
                    includeSemicolon: true);
                emit('$local++');
                break;
              case 1:
                emitVariableDeclaration(local, DartType.INT,
                    includeSemicolon: false, indent: false);
                emit(' in ');
                emitCollection(depth + 1, DartType.LIST_INT,
                    rhsFilter: rhsFilter);
                break;
              default:
                emitVariableDeclaration(local, DartType.INT,
                    includeSemicolon: false, indent: false);
                emit(' in ');
                emitCollection(depth + 1, DartType.SET_INT,
                    rhsFilter: rhsFilter);
                break;
            }
            localVars.removeLast(); // will get type
          });
          nest++;
          localVars.add(DartType.INT);
          emitNewline();
          emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
          localVars.removeLast();
          iterVars.removeLast();
          nest--;
          break;
        }
      default:
        emitElement(depth, tp, rhsFilter: rhsFilter);
        break;
    }
  }

  void emitCollection(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    var l, r;
    if (DartType.isListType(tp)) {
      var elementType = dartType.elementType(tp);
      l = '<${elementType.dartName}>[';
      r = ']';
    } else if (DartType.isSetType(tp)) {
      var elementType = dartType.elementType(tp);
      l = '<${elementType.dartName}>{';
      r = '}';
    } else if (DartType.isMapType(tp)) {
      var indexType = dartType.indexType(tp);
      var elementType = dartType.elementType(tp);
      l = '<${indexType.dartName},${elementType.dartName}>{';
      r = '}';
    } else {
      throw "Unrecognized collection type $tp";
    }
    emitWrapped([l, r], () {
      // Collection length decreases as depth increases.
      var collectionLength = max(1, 8 - depth);
      emitCommaSeparated(
          (int _) => emitCollectionElement(depth, tp, rhsFilter: rhsFilter),
          chooseOneUpTo(collectionLength),
          newline: DartType.isMapType(tp));
    }, shouldIndent: DartType.isMapType(tp));
  }

  void emitConstCollection(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    var l, r, canHaveElements;
    if (DartType.isListType(tp)) {
      var elementType = dartType.elementType(tp);
      l = 'const <${elementType.dartName}>[';
      r = ']';
      canHaveElements = true;
    } else if (DartType.isSetType(tp)) {
      var elementType = dartType.elementType(tp);
      l = 'const <${elementType.dartName}>{';
      r = '}';
      canHaveElements = (elementType != DartType.DOUBLE) &&
          (elementType != DartType.DOUBLE_NULLABLE);
    } else if (DartType.isMapType(tp)) {
      var indexType = dartType.indexType(tp);
      var elementType = dartType.elementType(tp);
      l = 'const <${indexType.dartName},${elementType.dartName}>{';
      r = '}';
      canHaveElements = (indexType != DartType.DOUBLE) &&
          (indexType != DartType.DOUBLE_NULLABLE);
    } else {
      throw "Unrecognized collection type $tp";
    }
    if (!canHaveElements) {
      // Dart does not like floating-point elements. A key would, for
      // example, yield "The key does not have a primitive operator '=='".
      // So emit an empty collection.
      emit(l);
      emit(r);
      return;
    }
    emitWrapped([l, r],
        () => emitElement(depth, tp, rhsFilter: rhsFilter, isConst: true),
        shouldIndent: DartType.isMapType(tp));
  }

  void emitLiteral(int depth, DartType tp,
      {bool smallPositiveValue = false, RhsFilter? rhsFilter}) {
    if (tp.isNullable) {
      if (choose(20) == 0) {
        emitNull();
        return;
      }
      tp = tp.toNonNullable();
    }
    // Randomly specialize interface if possible. E.g. num to int.
    tp = maybeSpecializeInterface(tp);
    if (tp == DartType.NULL) {
      emitNull();
    } else if (tp == DartType.BOOL) {
      emitBool();
    } else if (tp == DartType.INT) {
      if (smallPositiveValue) {
        emitSmallPositiveInt();
      } else {
        emitInt();
      }
    } else if (tp == DartType.DOUBLE) {
      emitDouble();
    } else if (tp == DartType.NUM) {
      emitNum(smallPositiveValue: smallPositiveValue);
    } else if (tp == DartType.STRING) {
      emitString();
    } else if (tp == DartType.ENDIAN) {
      // The Endian type doesn't have a public constructor, so we emit a
      // library call instead.
      emitLibraryCall(depth, tp);
    } else if (dartType.constructors(tp).isNotEmpty) {
      // Constructors serve as literals for non trivially constructable types.
      // Important note: We have to test for existence of a non trivial
      // constructor before testing for list type assiciation, since some types
      // like ListInt32 are of list type but can not be constructed
      // from a literal.
      emitConstructorOrLiteral(depth + 1, tp, rhsFilter: rhsFilter);
    } else if (DartType.isCollectionType(tp)) {
      final resetExprStmt = processExprOpen(tp);
      emitCollection(depth + 1, tp, rhsFilter: rhsFilter);
      processExprClose(resetExprStmt);
    } else {
      throw 'Can not emit literal for $tp';
    }
  }

  // Emit a constructor for a type, this can either be a trivial constructor
  // (i.e. parsed from a literal) or an actual function invocation.
  void emitConstructorOrLiteral(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
    // If there is at least one non trivial constructor for the type tp
    // select one of these constructors.
    if (dartType.hasConstructor(tp)) {
      var constructor = oneOfSet(dartType.constructors(tp));
      // There are two types of constructors, named constructors and 'empty'
      // constructors (e.g. X.fromList(...) and new X(...) respectively).
      // Empty constructors are invoked with new + type name, non-empty
      // constructors are static functions of the type.
      if (constructor.isNotEmpty) {
        emit('${tp.name}.$constructor');
      } else {
        // New is no longer necessary as of Dart 2, but is still supported.
        // Emit a `new` once in a while to ensure it's covered.
        emit('${rollDice(10) ? "new " : ""}${tp.name}');
      }
      emitParenWrapped(() {
        // Iterate over constructor parameters.
        var constructorParameters =
            dartType.constructorParameters(tp, constructor);
        if (constructorParameters == null) {
          throw 'No constructor parameters for ${tp.name}.$constructor';
        }
        emitCommaSeparated((int i) {
          // If we are emitting a constructor parameter, we want to use small
          // values to avoid programs that run out of memory.
          // TODO (felih): maybe allow occasionally?
          emitLiteral(depth + 1, constructorParameters[i],
              smallPositiveValue: true, rhsFilter: rhsFilter);
        }, constructorParameters.length);
      });
    } else {
      // Otherwise type can be constructed from a literal.
      emitLiteral(depth + 1, tp, rhsFilter: rhsFilter);
    }
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Pick an existing variable of the given type.
  String? pickScalarVar(DartType tp,
      {bool isLhs = false, RhsFilter? rhsFilter}) {
    // Randomly specialize interface type, unless emitting left hand side.
    if (!isLhs) tp = maybeSpecializeInterface(tp);
    // Collect all choices from globals, fields, locals, and parameters.
    var choices = <String>{};
    for (var i = 0; i < globalVars.length; i++) {
      if (tp == globalVars[i]) choices.add('$varName$i');
    }
    for (var i = 0; i < localVars.length; i++) {
      if (tp == localVars[i]) choices.add('$localName$i');
    }
    var fields = getCurrentFields();
    if (fields != null) {
      for (var i = 0; i < fields.length; i++) {
        if (tp == fields[i]) choices.add('$fieldName${currentClassIndex}_$i');
      }
    }
    var proto = getCurrentProto();
    if (proto != null) {
      // If recursion is allowed on the current method, the last parameter is
      // the recursion depth parameter. We should avoid reassigning the
      // recursion depth parameter to prevent infinite recursion.
      final endIndex =
          currentMethod!.recursionAllowed ? proto.length - 1 : proto.length;
      for (var i = 1; i < endIndex; i++) {
        if (tp == proto[i]) choices.add('$paramName$i');
      }
    }
    // Make modification of the iteration variable from the loop
    // body less likely.
    if (isLhs) {
      if (!rollDice(100)) {
        var cleanChoices = choices.difference(Set.from(iterVars));
        if (cleanChoices.isNotEmpty) {
          choices = cleanChoices;
        }
      }
    }
    // Filter out the current lhs of the expression to avoid recursive
    // assignments of the form x = x * x.
    if (rhsFilter != null && rhsFilter.shouldFilter) {
      var cleanChoices = choices.difference({rhsFilter.lhsVar});
      // If we have other choices of variables, use those.
      if (cleanChoices.isNotEmpty) {
        choices = cleanChoices;
      } else if (!isLhs) {
        // If we are emitting an rhs variable, we can emit a terminal.
        // note that if the variable type is a collection, this might
        // still result in a recursion.
        emitLiteral(0, tp);
        return null;
      }
      // Otherwise we have to risk creating a recursion.
    }
    // Then pick one.
    if (choices.isEmpty) {
      throw 'No variable to emit for type ${tp.name}';
    }

    return '${choices.elementAt(choose(choices.length))}';
  }

  String? emitScalarVar(DartType tp,
      {bool isLhs = false, RhsFilter? rhsFilter}) {
    final emittedVar = pickScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
    if (emittedVar != null) {
      if (rhsFilter != null && (emittedVar == rhsFilter.lhsVar)) {
        rhsFilter.consume();
      }
      emit(emittedVar);
    }
    return emittedVar;
  }

  String? emitSubscriptedVar(int depth, DartType tp,
      {bool isLhs = false, String? assignOp, RhsFilter? rhsFilter}) {
    String? ret;
    // Check if type tp is an indexable element of some other type.
    if (dartType.isIndexableElementType(tp)) {
      // Select a list or map type that contains elements of type tp.
      var iterType = oneOfSet(dartType.indexableElementTypes(tp));
      // For `collection[key] <op>= value` to work, collection must not be a
      // Map or Expando because their subscript operators return a nullable
      // type.
      if (assignOp != null && assignOp != "=") {
        while (!DartType.isListType(iterType)) {
          iterType = oneOfSet(dartType.indexableElementTypes(tp));
        }
      }
      // Get the index type for the respective list or map type.
      final indexType = dartType.indexType(iterType);
      // Emit a variable of the selected list or map type.
      ret = emitScalarVar(iterType, isLhs: isLhs, rhsFilter: rhsFilter);
      emitSquareBraceWrapped(() =>
          // Emit an expression resolving into the index type. For
          // collection type, only constant collections are used
          // to avoid rehashing the same value into many entries.
          DartType.isCollectionType(indexType)
              ? emitConstCollection(depth + 1, indexType)
              : emitExpr(depth + 1, indexType));
      // Map.[] and Expando.[] have a nullable result, but we should not write
      // map[key]! = value.
      if (!tp.isNullable && !isLhs) {
        emit('!');
      }
    } else {
      ret = emitScalarVar(tp,
          isLhs: isLhs, rhsFilter: rhsFilter); // resort to scalar
    }
    return ret;
  }

  String? emitVar(int depth, DartType tp,
      {bool isLhs = false, String? assignOp, RhsFilter? rhsFilter}) {
    switch (choose(2)) {
      case 0:
        return emitScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
      default:
        return emitSubscriptedVar(depth, tp,
            isLhs: isLhs, assignOp: assignOp, rhsFilter: rhsFilter);
    }
  }

  void emitTerminal(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    switch (choose(2)) {
      case 0:
        emitLiteral(depth, tp, rhsFilter: rhsFilter);
        break;
      default:
        emitVar(depth, tp, rhsFilter: rhsFilter);
        break;
    }
  }

  // Emit expression with unary operator: (~(x))
  void emitUnaryExpr(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    if (dartType.uniOps(tp).isEmpty) {
      return emitTerminal(depth, tp, rhsFilter: rhsFilter);
    }
    emitParenWrapped(() {
      emit(oneOfSet(dartType.uniOps(tp)));
      var uniOpParam = tp.toNonNullable();
      emitParenWrapped(
          () => emitExpr(depth + 1, uniOpParam, rhsFilter: rhsFilter));
    });
  }

  // Emit expression with binary operator: (x + y)
  void emitBinaryExpr(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    if (dartType.binOps(tp).isEmpty) {
      return emitLiteral(depth, tp);
    }

    var binop = oneOfSet(dartType.binOps(tp));
    var binOpParams = oneOfSet(dartType.binOpParameters(tp, binop));

    // Avoid recursive assignments of the form a = a * 100.
    if (binop == '*') {
      rhsFilter?.consume();
    }

    // Reduce the number of operations of type growable * large value
    // as these might lead to timeouts and/or oom errors.
    if (binop == '*' &&
        DartType.isGrowableType(binOpParams[0]) &&
        dartType.isInterfaceOfType(binOpParams[1], DartType.NUM)) {
      emitParenWrapped(() {
        emitExpr(depth + 1, binOpParams[0], rhsFilter: rhsFilter);
        emit(' $binop ');
        emitLiteral(depth + 1, binOpParams[1], smallPositiveValue: true);
      });
    } else if (binop == '*' &&
        DartType.isGrowableType(binOpParams[1]) &&
        dartType.isInterfaceOfType(binOpParams[0], DartType.NUM)) {
      emitParenWrapped(() {
        emitLiteral(depth + 1, binOpParams[0], smallPositiveValue: true);
        emit(' $binop ');
        emitExpr(depth + 1, binOpParams[1], rhsFilter: rhsFilter);
      });
    } else {
      emitParenWrapped(() {
        emitExpr(depth + 1, binOpParams[0], rhsFilter: rhsFilter);
        emit(' $binop ');
        emitExpr(depth + 1, binOpParams[1], rhsFilter: rhsFilter);
      });
    }
  }

  // Emit expression with ternary operator: (b ? x : y)
  void emitTernaryExpr(int depth, DartType tp, {RhsFilter? rhsFilter}) =>
      emitParenWrapped(() {
        emitExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter);
        emit(' ? ');
        emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
        emit(' : ');
        emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
      });

  // Emit expression with pre/post-increment/decrement operator: (x++)
  void emitPreOrPostExpr(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    if (tp == DartType.INT) {
      emitParenWrapped(() {
        var pre = coinFlip();
        if (pre) {
          emitPreOrPostOp(tp);
        }
        emitScalarVar(tp, isLhs: true);
        if (!pre) {
          emitPreOrPostOp(tp);
        }
      });
    } else {
      emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal
    }
  }

  bool isTypedDataFloatType(List<DartType> proto) {
    for (var i = 0; i < proto.length; ++i) {
      if (DartLib.typedDataFloatTypes.contains(proto[i])) {
        return true;
      }
    }
    return false;
  }

  // Emit library call.
  void emitLibraryCall(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
    var lib = getLibraryMethod(tp);
    if (lib == null || (!fp && isTypedDataFloatType(lib.proto))) {
      // We cannot find a library method, or we found a library method but its
      // prototype has a floating point type, and fp is disabled. This can only
      // happen for non-void types. In those cases, we resort to a literal.
      assert(tp != DartType.VOID);
      emitLiteral(depth + 1, tp, rhsFilter: rhsFilter);
      return;
    }
    emitParenWrapped(() {
      var prototype = lib.proto;
      // Receiver.
      if (prototype[0] != DartType.VOID) {
        emitParenWrapped(() => emitArg(
            depth + 1, prototype[0], lib.getRestriction(0),
            rhsFilter: rhsFilter));
        emit('.');
      }
      // Call.
      emit('${lib.name}');
      // Parameters.
      if (lib.isMethod) {
        emitParenWrapped(() {
          if (prototype[1] != DartType.VOID) {
            emitCommaSeparated(
                (int i) => emitArg(
                    depth + 1, prototype[i], lib.getRestriction(i),
                    rhsFilter: rhsFilter),
                prototype.length,
                start: 1);
          }
        });
      }
      // Add cast to avoid error of double or int being interpreted as num.
      if (dartType.isInterfaceOfType(tp, DartType.NUM)) {
        emit(' as ${tp.name}');
      }
    });
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Helper for a method call.
  bool pickedCall(int depth, DartType tp, List<Method> methods, int m,
      {RhsFilter? rhsFilter}) {
    for (var i = m - 1; i >= 0; i--) {
      if (tp == methods[i].returnType) {
        var isRecursiveCall = (currentMethod == methods[i]);
        if (isRecursiveCall && !methods[i].recursionAllowed) {
          continue;
        }
        methods[i].emitCall(depth + 1,
            rhsFilter: rhsFilter, isRecursiveCall: isRecursiveCall);
        return true;
      }
    }
    return false;
  }

  // Emit method call within the program.
  void emitMethodCall(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    // Only call an already emitted method or the current method to avoid mutual recursion.
    if (currentClassIndex == null) {
      // Outside a class but inside a method: call backward in global methods.
      if (currentMethodIndex != null &&
          pickedCall(depth, tp, globalMethods, currentMethodIndex! + 1,
              rhsFilter: rhsFilter)) {
        return;
      }
    } else {
      var classIndex = currentClassIndex;
      // Chase randomly up in class hierarchy.
      while (classParents[classIndex!] > 0) {
        if (coinFlip()) {
          break;
        }
        classIndex = classParents[classIndex];
      }
      var m1 = 0;
      // Inside a class: try to call backwards into current or parent class
      // methods first.
      if (currentMethodIndex == null || classIndex != currentClassIndex) {
        // If currently emitting the 'run' method or calling into a parent class
        // pick any of the current or parent class methods respectively.
        m1 = classMethods[classIndex].length;
      } else {
        // If calling into the current class from any method other than 'run'
        // pick one of the already emitted methods or the current method.
        // We allow simple recursion but avoid mutual recursion.
        // (to avoid infinite recursions).
        m1 = currentMethodIndex! + 1;
      }
      final m2 = globalMethods.length;
      if (pickedCall(depth, tp, classMethods[classIndex], m1,
              rhsFilter: rhsFilter) ||
          pickedCall(depth, tp, globalMethods, m2, rhsFilter: rhsFilter)) {
        return;
      }
    }
    emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal.
  }

  // Emit expression.
  void emitExpr(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
    final resetExprStmt = processExprOpen(tp);
    // Continuing nested expressions becomes less likely as the depth grows.
    if (choose(depth + 1) > exprDepth) {
      emitTerminal(depth, tp, rhsFilter: rhsFilter);
    } else {
      // Possibly nested expression.
      switch (choose(7)) {
        case 0:
          emitUnaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 1:
          emitBinaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 2:
          emitTernaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 3:
          emitPreOrPostExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 4:
          emitLibraryCall(depth, tp,
              rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
          break;
        case 5:
          emitMethodCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
          break;
        default:
          emitTerminal(depth, tp, rhsFilter: rhsFilter);
          break;
      }
    }
    processExprClose(resetExprStmt);
    if (includeSemicolon) {
      emit(';');
    }
  }

  //
  // Operators.
  //

  // Emit same type in-out increment operator.
  void emitPreOrPostOp(DartType tp) {
    assert(tp == DartType.INT);
    emit(oneOf(const <String>['++', '--']));
  }

  // Emit one type in, boolean out operator.
  void emitRelOp(DartType tp) {
    if (tp == DartType.INT || tp == DartType.DOUBLE) {
      emit(oneOf(const <String>[' > ', ' >= ', ' < ', ' <= ', ' != ', ' == ']));
    } else {
      emit(oneOf(const <String>[' != ', ' == ']));
    }
  }

  //
  // Library methods.
  //

  // Get a library method that returns given type.
  DartLib? getLibraryMethod(DartType tp) =>
      api.typeToLibraryMethods.containsKey(tp)
          ? oneOf(api.typeToLibraryMethods[tp]!)
          : null;

  // Emit a library argument, possibly subject to restrictions.
  void emitArg(int depth, DartType type, Restriction restriction,
      {RhsFilter? rhsFilter}) {
    if ((type == DartType.INT) && (restriction == Restriction.small)) {
      emitSmallPositiveInt();
    } else if ((type == DartType.DOUBLE) && !fp) {
      // resort to INT if floating point is disabled.
      emitExpr(depth, DartType.INT, rhsFilter: rhsFilter);
    } else if ((type == DartType.STRING) &&
        (restriction == Restriction.small)) {
      emitString(length: 2);
    } else {
      emitExpr(depth, type, rhsFilter: rhsFilter);
    }
  }

  //
  // Types.
  //

  List<DartType> fillTypes1({int limit = 4, bool isFfi = false}) {
    final list = <DartType>[];
    for (var i = 0, n = chooseOneUpTo(limit); i < n; i++) {
      if (isFfi) {
        list.add(fp ? oneOf([DartType.INT, DartType.DOUBLE]) : DartType.INT);
      } else {
        list.add(oneOfSet(dartType.allTypes));
      }
    }
    return list;
  }

  List<List<DartType>> fillTypes2(
      {bool isFfi = false, int limit2 = 4, int limit1 = 4}) {
    final list = <List<DartType>>[];
    for (var i = 0, n = chooseOneUpTo(limit2); i < n; i++) {
      list.add(fillTypes1(limit: limit1, isFfi: isFfi));
    }
    return list;
  }

  List<DartType>? getCurrentProto() {
    if (currentClassIndex != null) {
      if (currentMethodIndex != null) {
        return classMethods[currentClassIndex!][currentMethodIndex!].parameters;
      }
    } else if (currentMethodIndex != null) {
      return globalMethods[currentMethodIndex!].parameters;
    }
    return null;
  }

  List<DartType>? getCurrentFields() {
    if (currentClassIndex != null) {
      return classFields[currentClassIndex!];
    }
    return null;
  }

  void emitFfiType(DartType tp) {
    if (tp == DartType.INT) {
      emit(oneOf(
          const <String>['ffi.Int8', 'ffi.Int16', 'ffi.Int32', 'ffi.Int64']));
    } else if (tp == DartType.DOUBLE) {
      emit(oneOf(const <String>['ffi.Float', 'ffi.Double']));
    } else {
      throw 'Invalid FFI type ${tp.name}';
    }
  }

  void emitFfiTypedef(Method method) {
    var pars = method.parameters;
    emit('typedef ${method.name}Type = ');
    emitFfiType(pars[0]);
    emit(' Function');
    emitParenWrapped(
        () => emitCommaSeparated((int i) => emitFfiType(pars[i]), pars.length,
            start: 1),
        includeSemicolon: true);
    emitNewline();
    emitNewline();
  }

  //
  // Output.
  //

  // Emits a newline to the program.
  void emitNewline() => emit('', newline: true);

  // Emits indentation based on the current indentation count.
  void emitIndentation() => file.writeStringSync(' ' * indent);

  // Emits indented line to append to program.
  void emitLn(String line, {bool newline = true}) {
    emitIndentation();
    emit(line, newline: newline);
  }

  // Emits text to append to program.
  void emit(String txt, {bool newline = false}) {
    if (skipStmt || skipExpr) {
      return;
    }
    file.writeStringSync(txt);
    if (newline) {
      file.writeStringSync('\n');
    }
  }

  // Special return code to handle oom errors.
  static const oomExitCode = 254;

  // Random seed used to generate program.
  final int seed;

  // Enables floating-point operations.
  final bool fp;

  // Enables FFI method calls.
  final bool ffi;

  // Disables nested types.
  final bool flatTp;

  // File used for output.
  final RandomAccessFile file;

  // Library and ffi api.
  late DartApi api;

  // Program variables.
  late Random rand;
  int indent = 0;
  int nest = 0;
  int? currentClassIndex;
  Method? currentMethod;
  int? currentMethodIndex;

  // DartType instance.
  late DartType dartType;

  // Types of local variables currently in scope.
  late List<DartType?> localVars;

  // Types of global variables.
  late List<DartType> globalVars;

  // Names of currently active iterator variables.
  // These are tracked to avoid modifications within the loop body,
  // which can lead to infinite loops.
  late List<String?> iterVars;

  // List of all global methods.
  late List<Method> globalMethods;

  // Types of fields over all classes.
  late List<List<DartType>> classFields;

  // List of methods over all classes.
  late List<List<Method>> classMethods;

  // List of virtual functions per class. Map is from parent class index to List
  // of overloaded functions from that parent.
  late List<Map<int, List<int>>> virtualClassMethods;

  // Parent class indices for all classes.
  late List<int> classParents;

  // Minimization mode extensions.
  final bool minimize;
  BigInt? smask;
  BigInt? emask;
  bool skipStmt = false;
  bool skipExpr = false;
  bool skipExprCntr = false;
  int stmtCntr = 0;
  int exprCntr = 0;

  // Interesting characters.
  static const List<String> interestingChars = [
    '\\u2665',
    '\\u{1f600}', // rune
  ];

  // Regular characters.
  static const regularChars =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#&()+- ';

  // Interesting integer values.
  static const List<int> interestingIntegers = [
    0x0000000000000000,
    0x0000000000000001,
    0x000000007fffffff,
    0x0000000080000000,
    0x0000000080000001,
    0x00000000ffffffff,
    0x0000000100000000,
    0x0000000100000001,
    0x000000017fffffff,
    0x0000000180000000,
    0x0000000180000001,
    0x00000001ffffffff,
    0x7fffffff00000000,
    0x7fffffff00000001,
    0x7fffffff7fffffff,
    0x7fffffff80000000,
    0x7fffffff80000001,
    0x7fffffffffffffff,
    0x8000000000000000,
    0x8000000000000001,
    0x800000007fffffff,
    0x8000000080000000,
    0x8000000080000001,
    0x80000000ffffffff,
    0x8000000100000000,
    0x8000000100000001,
    0x800000017fffffff,
    0x8000000180000000,
    0x8000000180000001,
    0x80000001ffffffff,
    0xffffffff00000000,
    0xffffffff00000001,
    0xffffffff7fffffff,
    0xffffffff80000000,
    0xffffffff80000001,
    0xffffffffffffffff
  ];
}

// Generate seed. By default (no user-defined nonzero seed given),
// pick the system's best way of seeding randomness and then pick
// a user-visible nonzero seed.
int getSeed(String userSeed) {
  var seed = int.parse(userSeed);
  if (seed == 0) {
    final rand = Random();
    while (seed == 0) {
      seed = rand.nextInt(1 << 32);
    }
  }
  return seed;
}

/// Main driver when dartfuzz.dart is run stand-alone.
void main(List<String> arguments) {
  const kSeed = 'seed';
  const kFp = 'fp';
  const kFfi = 'ffi';
  const kFlat = 'flat';
  const kMini = 'mini';
  const kSMask = 'smask';
  const kEMask = 'emask';
  final parser = ArgParser()
    ..addOption(kSeed,
        help: 'random seed (0 forces time-based seed)', defaultsTo: '0')
    ..addFlag(kFp, help: 'enables floating-point operations', defaultsTo: true)
    ..addFlag(kFfi,
        help: 'enables FFI method calls (default: off)', defaultsTo: false)
    ..addFlag(kFlat,
        help: 'enables flat types (default: off)', defaultsTo: false)
    // Minimization mode extensions.
    ..addFlag(kMini,
        help: 'enables minimization mode (default: off)', defaultsTo: false)
    ..addOption(kSMask,
        help: 'Bitmask indicating which statements to omit'
            '(Bit=1 omits)',
        defaultsTo: '0')
    ..addOption(kEMask,
        help: 'Bitmask indicating which expressions to omit'
            '(Bit=1 omits)',
        defaultsTo: '0');
  var results;
  try {
    results = parser.parse(arguments);
  } catch (e) {
    print('Usage: dart dartfuzz.dart [OPTIONS] FILENAME\n${parser.usage}\n$e');
    exitCode = 255;
  }
  final seed = getSeed(results[kSeed]);
  final fp = results[kFp];
  final ffi = results[kFfi];
  final flatTp = results[kFlat];
  final file = File(results.rest.single).openSync(mode: FileMode.write);
  final minimize = results[kMini];
  final smask = BigInt.parse(results[kSMask]);
  final emask = BigInt.parse(results[kEMask]);
  final dartFuzz = DartFuzz(seed, fp, ffi, flatTp, file,
      minimize: minimize, smask: smask, emask: emask);
  dartFuzz.run();
  file.closeSync();
  // Print information that will be parsed by minimize.py
  if (minimize) {
    // Updated statement mask.
    // This might be different from the input parameter --smask
    // since masking a statement that contains nested statements leads to
    // those being masked as well.
    print(dartFuzz.smask!.toRadixString(10));
    // Total number of statements in the generated program.
    print(dartFuzz.stmtCntr);
    // Updated expression mask.
    // This might be different from the input parameter --emask
    // since masking a statement that contains expressions or
    // an expression that contains nested expressions leads to
    // those being masked as well.
    print(dartFuzz.emask!.toRadixString(10));
    // Total number of expressions in the generated program.
    print(dartFuzz.exprCntr);
  }
}
