// Copyright (c) 2012, 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.

/// Concurrent programming using _isolates_:
/// independent workers that are similar to threads
/// but don't share memory,
/// communicating only via messages.
///
/// *NOTE*: The `dart:isolate` library is currently only supported by the
/// [Dart Native](https://dart.dev/overview#platform) platform.

///
/// To use this library in your code:
/// ```dart
/// import 'dart:isolate';
/// ```
/// {@category VM}
library dart.isolate;

import "dart:_internal" show Since;
import "dart:async";
import "dart:typed_data" show ByteBuffer, TypedData, Uint8List;

part "capability.dart";

/// Thrown when an isolate cannot be created.
class IsolateSpawnException implements Exception {
  /// Error message reported by the spawn operation.
  final String message;
  @pragma("vm:entry-point")
  IsolateSpawnException(this.message);
  String toString() => "IsolateSpawnException: $message";
}

/// An isolated Dart execution context.
///
/// All Dart code runs in an isolate, and code can access classes and values
/// only from the same isolate. Different isolates can communicate by sending
/// values through ports (see [ReceivePort], [SendPort]).
///
/// An `Isolate` object is a reference to an isolate, usually different from
/// the current isolate.
/// It represents, and can be used to control, the other isolate.
///
/// When spawning a new isolate, the spawning isolate receives an `Isolate`
/// object representing the new isolate when the spawn operation succeeds.
///
/// Isolates run code in its own event loop, and each event may run smaller tasks
/// in a nested microtask queue.
///
/// An `Isolate` object allows other isolates to control the event loop
/// of the isolate that it represents, and to inspect the isolate,
/// for example by pausing the isolate or by getting events when the isolate
/// has an uncaught error.
///
/// The [controlPort] identifies and gives access to controlling the isolate,
/// and the [pauseCapability] and [terminateCapability] guard access
/// to some control operations.
/// For example, calling [pause] on an `Isolate` object created without a
/// [pauseCapability], has no effect.
///
/// The `Isolate` object provided by a spawn operation will have the
/// control port and capabilities needed to control the isolate.
/// New isolate objects can be created without some of these capabilities
/// if necessary, using the [Isolate.Isolate] constructor.
///
/// An `Isolate` object cannot be sent over a `SendPort`, but the control port
/// and capabilities can be sent, and can be used to create a new functioning
/// `Isolate` object in the receiving port's isolate.
class Isolate {
  /// Argument to `ping` and `kill`: Ask for immediate action.
  static const int immediate = 0;

  /// Argument to `ping` and `kill`: Ask for action before the next event.
  static const int beforeNextEvent = 1;

  /// Control port used to send control messages to the isolate.
  ///
  /// The control port identifies the isolate.
  ///
  /// An `Isolate` object allows sending control messages
  /// through the control port.
  ///
  /// Some control messages require a specific capability to be passed along
  /// with the message (see [pauseCapability] and [terminateCapability]),
  /// otherwise the message is ignored by the isolate.
  final SendPort controlPort;

  /// Capability granting the ability to pause the isolate.
  ///
  /// This capability is required by [pause].
  /// If the capability is `null`, or if it is not the correct pause capability
  /// of the isolate identified by [controlPort],
  /// then calls to [pause] will have no effect.
  ///
  /// If the isolate is spawned in a paused state, use this capability as
  /// argument to the [resume] method in order to resume the paused isolate.
  final Capability? pauseCapability;

  /// Capability granting the ability to terminate the isolate.
  ///
  /// This capability is required by [kill] and [setErrorsFatal].
  /// If the capability is `null`, or if it is not the correct termination
  /// capability of the isolate identified by [controlPort],
  /// then calls to those methods will have no effect.
  final Capability? terminateCapability;

  /// The name of the [Isolate] displayed for debug purposes.
  ///
  /// This can be set using the `debugName` parameter in [spawn] and [spawnUri].
  ///
  /// This name does not uniquely identify an isolate. Multiple isolates in the
  /// same process may have the same `debugName`.
  ///
  /// For a given isolate, this value will be the same as the values returned by
  /// `Dart_DebugName` in the C embedding API and the `debugName` property in
  /// [IsolateMirror].
  @Since("2.3")
  external String? get debugName;

  /// Creates a new [Isolate] object with a restricted set of capabilities.
  ///
  /// The port should be a control port for an isolate, as taken from
  /// another `Isolate` object.
  ///
  /// The capabilities should be the subset of the capabilities that are
  /// available to the original isolate.
  /// Capabilities of an isolate are locked to that isolate, and have no effect
  /// anywhere else, so the capabilities should come from the same isolate as
  /// the control port.
  ///
  /// Can also be used to create an [Isolate] object from a control port, and
  /// any available capabilities, that have been sent through a [SendPort].
  ///
  /// Example:
  /// ```dart
  /// Isolate isolate = findSomeIsolate();
  /// Isolate restrictedIsolate = Isolate(isolate.controlPort);
  /// untrustedCode(restrictedIsolate);
  /// ```
  /// This example creates a new `Isolate` object that cannot be used to
  /// pause or terminate the isolate. All the untrusted code can do is to
  /// inspect the isolate and see uncaught errors or when it terminates.
  Isolate(this.controlPort, {this.pauseCapability, this.terminateCapability});

  /// Runs [computation] in a new isolate and returns the result.
  ///
  /// ```dart
  /// int slowFib(int n) =>
  ///     n <= 1 ? 1 : slowFib(n - 1) + slowFib(n - 2);
  ///
  /// // Compute without blocking current isolate.
  /// var fib40 = await Isolate.run(() => slowFib(40));
  /// ```
  ///
  /// If [computation] is asynchronous (returns a `Future<R>`) then
  /// that future is awaited in the new isolate, completing the entire
  /// asynchronous computation, before returning the result.
  ///
  /// ```dart
  /// int slowFib(int n) =>
  ///     n <= 1 ? 1 : slowFib(n - 1) + slowFib(n - 2);
  /// Stream<int> fibStream() async* {
  ///   for (var i = 0;; i++) yield slowFib(i);
  /// }
  ///
  /// // Returns `Future<int>`.
  /// var fib40 = await Isolate.run(() => fibStream().elementAt(40));
  /// ```
  ///
  /// If [computation] throws, the isolate is terminated and this
  /// function throws the same error.
  ///
  /// ```dart import:convert
  /// Future<int> eventualError() async {
  ///   await Future.delayed(const Duration(seconds: 1));
  ///   throw StateError("In a bad state!");
  /// }
  ///
  /// try {
  ///   await Isolate.run(eventualError);
  /// } on StateError catch (e, s) {
  ///   print(e.message); // In a bad state!
  ///   print(LineSplitter.split("$s").first); // Contains "eventualError"
  /// }
  /// ```
  /// Any uncaught asynchronous errors will terminate the computation as well,
  /// but will be reported as a [RemoteError] because [addErrorListener]
  /// does not provide the original error object.
  ///
  /// The result is sent using [exit], which means it's sent to this
  /// isolate without copying.
  ///
  /// The [computation] function and its result (or error) must be
  /// sendable between isolates.
  ///
  /// The [debugName] is only used to name the new isolate for debugging.
  @Since("2.17")
  static Future<R> run<R>(FutureOr<R> computation(), {String? debugName}) {
    var result = Completer<R>();
    var resultPort = RawReceivePort();
    resultPort.handler = (response) {
      resultPort.close();
      if (response == null) {
        // onExit handler message, isolate terminated without sending result.
        result.completeError(
            RemoteError("Computation ended without result", ""),
            StackTrace.empty);
        return;
      }
      var list = response as List<Object?>;
      if (list.length == 2) {
        var remoteError = list[0];
        var remoteStack = list[1];
        if (remoteStack is StackTrace) {
          // Typed error.
          result.completeError(remoteError!, remoteStack);
        } else {
          // onError handler message, uncaught async error.
          // Both values are strings, so calling `toString` is efficient.
          var error =
              RemoteError(remoteError.toString(), remoteStack.toString());
          result.completeError(error, error.stackTrace);
        }
      } else {
        assert(list.length == 1);
        result.complete(list[0] as R);
      }
    };
    try {
      Isolate.spawn(_RemoteRunner._remoteExecute,
              _RemoteRunner<R>(computation, resultPort.sendPort),
              onError: resultPort.sendPort,
              onExit: resultPort.sendPort,
              errorsAreFatal: true,
              debugName: debugName)
          .then<void>((_) {}, onError: (error, stack) {
        // Sending the computation failed asynchronously.
        // Do not expect a response, report the error asynchronously.
        resultPort.close();
        result.completeError(error, stack);
      });
    } on Object {
      // Sending the computation failed synchronously.
      // This is not expected to happen, but if it does,
      // the synchronous error is respected and rethrown synchronously.
      resultPort.close();
      rethrow;
    }
    return result.future;
  }

  /// An [Isolate] object representing the current isolate.
  ///
  /// The current isolate for code using [current]
  /// is the isolate running the code.
  ///
  /// The isolate object provides the capabilities required to inspect,
  /// pause or kill the isolate, and allows granting these capabilities
  /// to others.
  ///
  /// It is possible to pause the current isolate, but doing so *without*
  /// first passing the ability to resume it again to another isolate,
  /// is a sure way to hang your program.
  external static Isolate get current;

  /// The location of the package configuration of the current isolate, if any.
  ///
  /// If the isolate has not been setup for package resolution,
  /// this location is `null`,
  /// otherwise it is a URI referencing the package config file.
  external static Future<Uri?> get packageConfig;

  /// Maps a `package:` URI to a non-package Uri.
  ///
  /// If there is no valid mapping from the `package:` URI in the current
  /// isolate, then this call returns `null`. Non-`package:` URIs are
  /// returned unmodified.
  external static Future<Uri?> resolvePackageUri(Uri packageUri);

  /// Creates and spawns an isolate that shares the same code as the current
  /// isolate.
  ///
  /// The argument [entryPoint] specifies the initial function to call
  /// in the spawned isolate.
  /// The entry-point function is invoked in the new isolate with [message]
  /// as the only argument.
  ///
  /// The function must be a top-level function or a static method
  /// that can be called with a single argument,
  /// that is, a compile-time constant function value
  /// which accepts at least one positional parameter
  /// and has at most one required positional parameter.
  /// The function may accept any number of optional parameters,
  /// as long as it *can* be called with just a single argument.
  /// The function must not be the value of a function expression
  /// or an instance method tear-off.
  ///
  /// Usually the initial [message] contains a [SendPort] so
  /// that the spawner and spawnee can communicate with each other.
  ///
  /// If the [paused] parameter is set to `true`,
  /// the isolate will start up in a paused state,
  /// just before calling the [entryPoint] function with the [message],
  /// as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
  /// To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
  ///
  /// If the [errorsAreFatal], [onExit] and/or [onError] parameters are provided,
  /// the isolate will act as if, respectively, [setErrorsFatal],
  /// [addOnExitListener] and [addErrorListener] were called with the
  /// corresponding parameter and was processed before the isolate starts
  /// running.
  ///
  /// If [debugName] is provided, the spawned [Isolate] will be identifiable by
  /// this name in debuggers and logging.
  ///
  /// If [errorsAreFatal] is omitted, the platform may choose a default behavior
  /// or inherit the current isolate's behavior.
  ///
  /// You can also call the [setErrorsFatal], [addOnExitListener] and
  /// [addErrorListener] methods on the returned isolate, but unless the
  /// isolate was started as [paused], it may already have terminated
  /// before those methods can complete.
  ///
  /// Returns a future which will complete with an [Isolate] instance if the
  /// spawning succeeded. It will complete with an error otherwise.
  external static Future<Isolate> spawn<T>(
      void entryPoint(T message), T message,
      {bool paused = false,
      bool errorsAreFatal = true,
      SendPort? onExit,
      SendPort? onError,
      @Since("2.3") String? debugName});

  /// Creates and spawns an isolate that runs the code from the library with
  /// the specified URI.
  ///
  /// The isolate starts executing the top-level `main` function of the library
  /// with the given URI.
  ///
  /// The target `main` must be callable with zero, one or two arguments.
  /// Examples:
  ///
  /// * `main()`
  /// * `main(args)`
  /// * `main(args, message)`
  ///
  /// When present, the parameter `args` is set to the provided [args] list.
  /// When present, the parameter `message` is set to the initial [message].
  ///
  /// If the [paused] parameter is set to `true`,
  /// the isolate will start up in a paused state,
  /// as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
  /// To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
  ///
  /// If the [errorsAreFatal], [onExit] and/or [onError] parameters are provided,
  /// the isolate will act as if, respectively, [setErrorsFatal],
  /// [addOnExitListener] and [addErrorListener] were called with the
  /// corresponding parameter and was processed before the isolate starts
  /// running.
  ///
  /// You can also call the [setErrorsFatal], [addOnExitListener] and
  /// [addErrorListener] methods on the returned isolate, but unless the
  /// isolate was started as [paused], it may already have terminated
  /// before those methods can complete.
  ///
  /// If the [checked] parameter is set to `true` or `false`,
  /// the new isolate will run code in checked mode (enabling asserts and type
  /// checks), respectively in production mode (disabling asserts and type
  /// checks), if possible. If the parameter is omitted, the new isolate will
  /// inherit the value from the current isolate.
  ///
  /// In Dart2 strong mode, the `checked` parameter only controls asserts, but
  /// not type checks.
  ///
  /// It may not always be possible to honor the `checked` parameter.
  /// If the isolate code was pre-compiled, it may not be possible to change
  /// the checked mode setting dynamically.
  /// In that case, the `checked` parameter is ignored.
  ///
  /// WARNING: The [checked] parameter is not implemented on all platforms yet.
  ///
  /// If the [packageConfig] parameter is provided, then it is used to find the
  /// location of a package resolution configuration file for the spawned
  /// isolate.
  ///
  /// If the [automaticPackageResolution] parameter is provided, then the
  /// location of the package sources in the spawned isolate is automatically
  /// determined.
  ///
  /// The [environment] is a mapping from strings to strings which the
  /// spawned isolate uses when looking up [String.fromEnvironment] values.
  /// The system may add its own entries to environment as well.
  /// If `environment` is omitted, the spawned isolate has the same environment
  /// declarations as the spawning isolate.
  ///
  /// WARNING: The [environment] parameter is not implemented on all
  /// platforms yet.
  ///
  /// If [debugName] is provided, the spawned [Isolate] will be identifiable by
  /// this name in debuggers and logging.
  ///
  /// Returns a future that will complete with an [Isolate] instance if the
  /// spawning succeeded. It will complete with an error otherwise.
  external static Future<Isolate> spawnUri(
      Uri uri,
      List<String> args,
      var message,
      {bool paused = false,
      SendPort? onExit,
      SendPort? onError,
      bool errorsAreFatal = true,
      bool? checked,
      Map<String, String>? environment,
      @Deprecated('The packages/ dir is not supported in Dart 2')
          Uri? packageRoot,
      Uri? packageConfig,
      bool automaticPackageResolution = false,
      @Since("2.3")
          String? debugName});

  /// Requests the isolate to pause.
  ///
  /// When the isolate receives the pause command, it stops
  /// processing events from the event loop queue.
  /// It may still add new events to the queue in response to, e.g., timers
  /// or receive-port messages. When the isolate is resumed,
  /// it starts handling the already enqueued events.
  ///
  /// The pause request is sent through the isolate's command port,
  /// which bypasses the receiving isolate's event loop.
  /// The pause takes effect when it is received, pausing the event loop
  /// as it is at that time.
  ///
  /// The [resumeCapability] is used to identity the pause,
  /// and must be used again to end the pause using [resume].
  /// If [resumeCapability] is omitted, a new capability object is created
  /// and used instead.
  ///
  /// If an isolate is paused more than once using the same capability,
  /// only one resume with that capability is needed to end the pause.
  ///
  /// If an isolate is paused using more than one capability,
  /// each pause must be individually ended before the isolate resumes.
  ///
  /// Returns the capability that must be used to end the pause.
  /// This is either [resumeCapability], or a new capability when
  /// [resumeCapability] is omitted.
  ///
  /// If [pauseCapability] is `null`, or it's not the pause capability
  /// of the isolate identified by [controlPort],
  /// the pause request is ignored by the receiving isolate.
  Capability pause([Capability? resumeCapability]) {
    resumeCapability ??= Capability();
    _pause(resumeCapability);
    return resumeCapability;
  }

  /// Internal implementation of [pause].
  external void _pause(Capability resumeCapability);

  /// Resumes a paused isolate.
  ///
  /// Sends a message to an isolate requesting that it ends a pause
  /// that was previously requested.
  ///
  /// When all active pause requests have been cancelled, the isolate
  /// will continue processing events and handling normal messages.
  ///
  /// If the [resumeCapability] is not one that has previously been used
  /// to pause the isolate, or it has already been used to resume from
  /// that pause, the resume call has no effect.
  external void resume(Capability resumeCapability);

  /// Requests an exit message on [responsePort] when the isolate terminates.
  ///
  /// The isolate will send [response] as a message on [responsePort] as the last
  /// thing before it terminates. It will run no further code after the message
  /// has been sent.
  ///
  /// Adding the same port more than once will only cause it to receive one exit
  /// message, using the last response value that was added,
  /// and it only needs to be removed once using [removeOnExitListener].
  ///
  /// If the isolate has terminated before it can receive this request,
  /// no exit message will be sent.
  ///
  /// The [response] object must follow the same restrictions as enforced by
  /// [SendPort.send].
  /// It is recommended to only use simple values that can be sent to all
  /// isolates, like `null`, booleans, numbers or strings.
  ///
  /// Since isolates run concurrently, it's possible for it to exit before the
  /// exit listener is established, and in that case no response will be
  /// sent on [responsePort].
  /// To avoid this, either use the corresponding parameter to the spawn
  /// function, or start the isolate paused, add the listener and
  /// then resume the isolate.
  /* TODO(lrn): Can we do better? Can the system recognize this message and
   * send a reply if the receiving isolate is dead?
   */
  external void addOnExitListener(SendPort responsePort, {Object? response});

  /// Stops listening for exit messages from the isolate.
  ///
  /// Requests for the isolate to not send exit messages on [responsePort].
  /// If the isolate isn't expecting to send exit messages on [responsePort],
  /// because the port hasn't been added using [addOnExitListener],
  /// or because it has already been removed, the request is ignored.
  ///
  /// If the same port has been passed via [addOnExitListener] more than once,
  /// only one call to `removeOnExitListener` is needed to stop it from receiving
  /// exit messages.
  ///
  /// Closing the receive port that is associated with the [responsePort] does
  /// not stop the isolate from sending uncaught errors, they are just going to
  /// be lost.
  ///
  /// An exit message may still be sent if the isolate terminates
  /// before this request is received and processed.
  external void removeOnExitListener(SendPort responsePort);

  /// Sets whether uncaught errors will terminate the isolate.
  ///
  /// If errors are fatal, any uncaught error will terminate the isolate
  /// event loop and shut down the isolate.
  ///
  /// This call requires the [terminateCapability] for the isolate.
  /// If the capability is absent or incorrect, no change is made.
  ///
  /// Since isolates run concurrently, it's possible for the receiving isolate
  /// to exit due to an error, before a request, using this method, has been
  /// received and processed.
  /// To avoid this, either use the corresponding parameter to the spawn
  /// function, or start the isolate paused, set errors non-fatal and
  /// then resume the isolate.
  external void setErrorsFatal(bool errorsAreFatal);

  /// Requests the isolate to shut down.
  ///
  /// The isolate is requested to terminate itself.
  /// The [priority] argument specifies when this must happen.
  ///
  /// The [priority], when provided, must be one of [immediate] or
  /// [beforeNextEvent] (the default).
  /// The shutdown is performed at different times depending on the priority:
  ///
  /// * `immediate`: The isolate shuts down as soon as possible.
  ///     Control messages are handled in order, so all previously sent control
  ///     events from this isolate will all have been processed.
  ///     The shutdown should happen no later than if sent with
  ///     `beforeNextEvent`.
  ///     It may happen earlier if the system has a way to shut down cleanly
  ///     at an earlier time, even during the execution of another event.
  /// * `beforeNextEvent`: The shutdown is scheduled for the next time
  ///     control returns to the event loop of the receiving isolate,
  ///     after the current event, and any already scheduled control events,
  ///     are completed.
  ///
  /// If [terminateCapability] is `null`, or it's not the terminate capability
  /// of the isolate identified by [controlPort],
  /// the kill request is ignored by the receiving isolate.
  external void kill({int priority = beforeNextEvent});

  /// Requests that the isolate send [response] on the [responsePort].
  ///
  /// The [response] object must follow the same restrictions as enforced by
  /// [SendPort.send].
  /// It is recommended to only use simple values that can be sent to all
  /// isolates, like `null`, booleans, numbers or strings.
  ///
  /// If the isolate is alive, it will eventually send `response`
  /// (defaulting to `null`) on the response port.
  ///
  /// The [priority] must be one of [immediate] or [beforeNextEvent].
  /// The response is sent at different times depending on the ping type:
  ///
  /// * `immediate`: The isolate responds as soon as it receives the
  ///     control message. This is after any previous control message
  ///     from the same isolate has been received and processed,
  ///     but may be during execution of another event.
  /// * `beforeNextEvent`: The response is scheduled for the next time
  ///     control returns to the event loop of the receiving isolate,
  ///     after the current event, and any already scheduled control events,
  ///     are completed.
  external void ping(SendPort responsePort,
      {Object? response, int priority = immediate});

  /// Requests that uncaught errors of the isolate are sent back to [port].
  ///
  /// The errors are sent back as two-element lists.
  /// The first element is a `String` representation of the error, usually
  /// created by calling `toString` on the error.
  /// The second element is a `String` representation of an accompanying
  /// stack trace, or `null` if no stack trace was provided.
  /// To convert this back to a [StackTrace] object, use [StackTrace.fromString].
  ///
  /// Listening using the same port more than once does nothing.
  /// A port will only receive each error once,
  /// and will only need to be removed once using [removeErrorListener].
  ///
  /// Closing the receive port that is associated with the port does not stop
  /// the isolate from sending uncaught errors, they are just going to be lost.
  /// Instead use [removeErrorListener] to stop receiving errors on [port].
  ///
  /// Since isolates run concurrently, it's possible for it to exit before the
  /// error listener is established. To avoid this, start the isolate paused,
  /// add the listener and then resume the isolate.
  external void addErrorListener(SendPort port);

  /// Stops listening for uncaught errors from the isolate.
  ///
  /// Requests for the isolate to not send uncaught errors on [port].
  /// If the isolate isn't expecting to send uncaught errors on [port],
  /// because the port hasn't been added using [addErrorListener],
  /// or because it has already been removed, the request is ignored.
  ///
  /// If the same port has been passed via [addErrorListener] more than once,
  /// only one call to `removeErrorListener` is needed to stop it from receiving
  /// uncaught errors.
  ///
  /// Uncaught errors message may still be sent by the isolate
  /// until this request is received and processed.
  external void removeErrorListener(SendPort port);

  /// Returns a broadcast stream of uncaught errors from the isolate.
  ///
  /// Each error is provided as an error event on the stream.
  ///
  /// The actual error object and stackTraces will not necessarily
  /// be the same object types as in the actual isolate, but they will
  /// always have the same [Object.toString] result.
  ///
  /// This stream is based on [addErrorListener] and [removeErrorListener].
  Stream get errors {
    StreamController controller = StreamController.broadcast(sync: true);
    RawReceivePort? port;
    void handleError(Object? message) {
      var listMessage = message as List<Object?>;
      var errorDescription = listMessage[0] as String;
      var stackDescription = listMessage[1] as String;
      var error = RemoteError(errorDescription, stackDescription);
      controller.addError(error, error.stackTrace);
    }

    controller.onListen = () {
      RawReceivePort receivePort = RawReceivePort(handleError);
      port = receivePort;
      this.addErrorListener(receivePort.sendPort);
    };
    controller.onCancel = () {
      var listenPort = port!;
      port = null;
      this.removeErrorListener(listenPort.sendPort);
      listenPort.close();
    };
    return controller.stream;
  }

  /// Terminates the current isolate synchronously.
  ///
  /// This operation is potentially dangerous and should be used judiciously.
  /// The isolate stops operating *immediately*. It throws if the optional
  /// [message] does not adhere to the limitations on what can be sent from one
  /// isolate to another (see [SendPort.send] for more details). It also throws
  /// if a [finalMessagePort] is associated with an isolate spawned outside of
  /// current isolate group, spawned via [spawnUri].
  ///
  /// If successful, a call to this method does not return. Pending `finally`
  /// blocks are not executed, control flow will not go back to the event loop,
  /// scheduled asynchronous asks will never run, and even pending isolate
  /// control commands may be ignored. (The isolate will send messages to ports
  /// already registered using [Isolate.addOnExitListener], but no further Dart
  /// code will run in the isolate.)
  ///
  /// If [finalMessagePort] is provided, and the [message] can be sent through
  /// it (see [SendPort.send] for more details), then the message is sent
  /// through that port as the final operation of the current isolate. The
  /// isolate terminates immediately after that [SendPort.send] call returns.
  ///
  /// If the port is a native port -- one provided by [ReceivePort.sendPort] or
  /// [RawReceivePort.sendPort] -- the system may be able to send this final
  /// message more efficiently than normal port communication between live
  /// isolates. In these cases this final message object graph will be
  /// reassigned to the receiving isolate without copying. Further, the
  /// receiving isolate will in most cases be able to receive the message
  /// in constant time.
  external static Never exit([SendPort? finalMessagePort, Object? message]);
}

/// Sends messages to its [ReceivePort]s.
///
/// [SendPort]s are created from [ReceivePort]s. Any message sent through
/// a [SendPort] is delivered to its corresponding [ReceivePort]. There might be
/// many [SendPort]s for the same [ReceivePort].
///
/// [SendPort]s can be transmitted to other isolates, and they preserve equality
/// when sent.
abstract class SendPort implements Capability {
  /// Sends an asynchronous [message] through this send port, to its
  /// corresponding [ReceivePort].
  ///
  /// The transitive object graph of [message] can contain the following
  /// objects:
  ///   - [Null]
  ///   - [bool]
  ///   - [int]
  ///   - [double]
  ///   - [String]
  ///   - [List] or [Map] (whose elements are any of these)
  ///   - [TransferableTypedData]
  ///   - [SendPort]
  ///   - [Capability]
  ///
  /// If the sender and receiver isolate share the same code (e.g. isolates
  /// created via [Isolate.spawn]), the transitive object graph of [message] can
  /// contain any object, with the following exceptions:
  ///
  ///   - Objects with native resources (subclasses of e.g.
  ///     `NativeFieldWrapperClass1`). A [Socket] object for example referrs
  ///     internally to objects that have native resources attached and can
  ///     therefore not be sent.
  ///   - [ReceivePort]
  ///   - [DynamicLibrary]
  ///   - [Pointer]
  ///   - [UserTag]
  ///   - `MirrorReference`
  ///
  /// Apart from those exceptions any object can be sent. Objects that are
  /// identified as immutable (e.g. strings) will be shared whereas all other
  /// objects will be copied.
  ///
  /// The send happens immediately and may have a linear time cost to copy the
  /// transtive object graph. The send itself doesn't block (i.e. doesn't wait
  /// until the receiver has received the message). The corresponding receive
  /// port can receive the message as soon as its isolate's event loop is ready
  /// to deliver it, independently of what the sending isolate is doing.
  ///
  /// Note: Due to an implementation choice the Dart VM made for how closures
  /// represent captured state, closures can currently capture more state than
  /// they need, which can cause the transitive closure to be larger than
  /// needed. Open bug to address this: http://dartbug.com/36983
  void send(Object? message);

  /// Tests whether [other] is a [SendPort] pointing to the same
  /// [ReceivePort] as this one.
  bool operator ==(var other);

  /// A hash code for this send port that is consistent with the == operator.
  int get hashCode;
}

/// Together with [SendPort], the only means of communication between isolates.
///
/// [ReceivePort]s have a `sendPort` getter which returns a [SendPort].
/// Any message that is sent through this [SendPort]
/// is delivered to the [ReceivePort] it has been created from. There, the
/// message is dispatched to the `ReceivePort`'s listener.
///
/// A [ReceivePort] is a non-broadcast stream. This means that it buffers
/// incoming messages until a listener is registered. Only one listener can
/// receive messages. See [Stream.asBroadcastStream] for transforming the port
/// to a broadcast stream.
///
/// A [ReceivePort] may have many [SendPort]s.
abstract class ReceivePort implements Stream<dynamic> {
  /// Opens a long-lived port for receiving messages.
  ///
  /// A [ReceivePort] is a non-broadcast stream. This means that it buffers
  /// incoming messages until a listener is registered. Only one listener can
  /// receive messages. See [Stream.asBroadcastStream] for transforming the port
  /// to a broadcast stream.
  ///
  /// The optional `debugName` parameter can be set to associate a name with
  /// this port that can be displayed in tooling.
  ///
  /// A receive port is closed by canceling its subscription.
  external factory ReceivePort([String debugName = '']);

  /// Creates a [ReceivePort] from a [RawReceivePort].
  ///
  /// The handler of the given [rawPort] is overwritten during the construction
  /// of the result.
  external factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort);

  /// Listen for events from [Stream].
  ///
  /// See [Stream.listen].
  ///
  /// Note that [onError] and [cancelOnError] are ignored since a [ReceivePort]
  /// will never receive an error.
  ///
  /// The [onDone] handler will be called when the stream closes.
  /// The stream closes when [close] is called.
  StreamSubscription<dynamic> listen(void onData(var message)?,
      {Function? onError, void onDone()?, bool? cancelOnError});

  /// Closes the receive port.
  ///
  /// No further events will be received by the receive port,
  /// or emitted as stream events.
  ///
  /// If [listen] has been called and the [StreamSubscription] has not
  /// been canceled yet, the subscription will be closed with a "done"
  /// event.
  ///
  /// If the stream has already been canceled this method has no effect.
  void close();

  /// A [SendPort] which sends messages to this receive port.
  SendPort get sendPort;
}

/// A low-level asynchronous message receiver.
///
/// A [RawReceivePort] is low level feature, and is not [Zone] aware.
/// The [handler] will always be invoked  in the [Zone.root] zone.
///
/// The port cannot be paused. The data-handler must be set before the first
/// message is received, otherwise the message is lost.
///
/// Messages can be sent to this port using [sendPort].
abstract class RawReceivePort {
  /// Opens a long-lived port for receiving messages.
  ///
  /// A [RawReceivePort] is low level and does not work with [Zone]s. It
  /// cannot be paused. The data-handler must be set before the first
  /// message is received, otherwise the message is lost.
  ///
  /// If [handler] is provided, it's set as the [RawReceivePort.handler].
  ///
  /// The optional `debugName` parameter can be set to associate a name with
  /// this port that can be displayed in tooling.
  external factory RawReceivePort([Function? handler, String debugName = '']);

  /// Sets the handler that is invoked for every incoming message.
  ///
  /// The handler is invoked in the [Zone.root] zone.
  /// If the handler should be invoked in the current zone, do:
  /// ```dart
  /// rawPort.handler = Zone.current.bind(actualHandler);
  /// ```
  ///
  /// The handler must be a function which can accept one argument
  /// of the type of the messages sent to this port.
  /// This means that if it is known that messages will all be [String]s,
  /// a handler of type `void Function(String)` can be used.
  /// The function is invoked dynamically with the actual messages,
  /// and if this invocation fails,
  /// the error becomes a top-level uncaught error in the [Zone.root] zone.
  // TODO(44659): Change parameter type to `void Function(Never)` to only
  // accept functions which can be called with one argument.
  void set handler(Function? newHandler);

  /// Closes the port.
  ///
  /// After a call to this method, any incoming message is silently dropped.
  /// The [handler] will never be called again.
  void close();

  /// Returns a [SendPort] that sends messages to this raw receive port.
  SendPort get sendPort;
}

/// Description of an error from another isolate.
///
/// This error has the same `toString()` and `stackTrace.toString()` behavior
/// as the original error, but has no other features of the original error.
class RemoteError implements Error {
  final String _description;
  final StackTrace stackTrace;
  RemoteError(String description, String stackDescription)
      : _description = description,
        stackTrace = StackTrace.fromString(stackDescription);
  String toString() => _description;
}

/// An efficiently transferable sequence of byte values.
///
/// A [TransferableTypedData] is created from a number of bytes.
/// This will take time proportional to the number of bytes.
///
/// The [TransferableTypedData] can be moved between isolates, so
/// sending it through a send port will only take constant time.
///
/// When sent this way, the local transferable can no longer be materialized,
/// and the received object is now the only way to materialize the data.
@Since("2.3.2")
abstract class TransferableTypedData {
  /// Creates a new [TransferableTypedData] containing the bytes of [list].
  ///
  /// It must be possible to create a single [Uint8List] containing the
  /// bytes, so if there are more bytes than what the platform allows in
  /// a single [Uint8List], then creation fails.
  external factory TransferableTypedData.fromList(List<TypedData> list);

  /// Creates a new [ByteBuffer] containing the bytes stored in this [TransferableTypedData].
  ///
  /// The [TransferableTypedData] is a cross-isolate single-use resource.
  /// This method must not be called more than once on the same underlying
  /// transferable bytes, even if the calls occur in different isolates.
  ByteBuffer materialize();
}

/// Parameter object used by [Isolate.run].
///
/// The [_remoteExecute] function is run in a new isolate with a
/// [_RemoteRunner] object as argument.
class _RemoteRunner<R> {
  /// User computation to run.
  final FutureOr<R> Function() computation;

  /// Port to send isolate computation result on.
  ///
  /// Only one object is ever sent on this port.
  /// If the value is `null`, it is sent by the isolate's "on-exit" handler
  /// when the isolate terminates without otherwise sending value.
  /// If the value is a list with one element,
  /// then it is the result value of the computation.
  /// Otherwise it is a list with two elements representing an error.
  /// If the error is sent by the isolate's "on-error" uncaught error handler,
  /// then the list contains two strings. This also terminates the isolate.
  /// If sent manually by this class, after capturing the error,
  /// the list contains one non-`null` [Object] and one [StackTrace].
  final SendPort resultPort;

  _RemoteRunner(this.computation, this.resultPort);

  /// Run in a new isolate to get the result of [computation].
  ///
  /// The result is sent back on [resultPort] as a single-element list.
  /// A two-element list sent on the same port is an error result.
  /// When sent by this function, it's always an object and a [StackTrace].
  /// (The same port listens on uncaught errors from the isolate, which
  /// sends two-element lists containing [String]s instead).
  static void _remoteExecute(_RemoteRunner<Object?> runner) {
    runner._run();
  }

  void _run() async {
    R result;
    try {
      var potentiallyAsyncResult = computation();
      if (potentiallyAsyncResult is Future<R>) {
        result = await potentiallyAsyncResult;
      } else {
        result = potentiallyAsyncResult;
      }
    } catch (e, s) {
      // If sending fails, the error becomes an uncaught error.
      Isolate.exit(resultPort, _list2(e, s));
    }
    Isolate.exit(resultPort, _list1(result));
  }

  /// Helper function to create a one-element non-growable list.
  static List<Object?> _list1(Object? value) => List.filled(1, value);

  /// Helper function to create a two-element non-growable list.
  static List<Object?> _list2(Object? value1, Object? value2) =>
      List.filled(2, value1)..[1] = value2;
}
