// 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";

// Examples can assume:
// Isolate findSomeIsolate() => Isolate.current;
// void untrustedCode(Isolate isolate) {}
// RawReceivePort rawPort = RawReceivePort();
// void actualHandler() {}

/// 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});

  /// 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.
  ///
  /// One can expect the base memory overhead of an isolate to be in the order
  /// of 30 kb.
  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]
  ///   - [Finalizable]
  ///   - [Finalizer]
  ///   - [NativeFinalizer]
  ///   - [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
  /// transitive 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 import:async
  /// rawPort.handler = Zone.current.bindCallback(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();
}
