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

/// Foreign Function Interface for interoperability with the C programming language.
///
/// For further details, please see: https://dart.dev/server/c-interop.
///
/// {@category VM}
@Since('2.6')
library dart.ffi;

import 'dart:_internal' show Since;
import 'dart:isolate';
import 'dart:typed_data';

part 'abi.dart';
part 'abi_specific.dart';
part 'native_type.dart';
part 'native_finalizer.dart';
part 'allocation.dart';
part 'annotations.dart';
part 'c_type.dart';
part 'dynamic_library.dart';
part 'struct.dart';
part 'union.dart';

/// Number of bytes used by native type T.
///
/// Includes padding and alignment of structs.
///
/// This function must be invoked with a compile-time constant [T].
external int sizeOf<T extends SizedNativeType>();

/// Represents a pointer into the native C memory corresponding to 'NULL', e.g.
/// a pointer with address 0.
final Pointer<Never> nullptr = Pointer.fromAddress(0);

/// Represents a pointer into the native C memory. Cannot be extended.
@pragma('vm:entry-point')
@pragma("wasm:entry-point")
final class Pointer<T extends NativeType> implements SizedNativeType {
  /// Construction from raw integer.
  external factory Pointer.fromAddress(int ptr);

  /// Convert Dart function to a C function pointer, automatically marshalling
  /// the arguments and return value
  ///
  /// If an exception is thrown while calling `f()`, the native function will
  /// return `exceptionalReturn`, which must be assignable to return type of `f`.
  ///
  /// The returned function address can only be invoked on the mutator (main)
  /// thread of the current isolate. It will abort the process if invoked on any
  /// other thread. Use [NativeCallable.listener] to create callbacks that can
  /// be invoked from any thread.
  ///
  /// The pointer returned will remain alive for the duration of the current
  /// isolate's lifetime. After the isolate it was created in is terminated,
  /// invoking it from native code will cause undefined behavior.
  ///
  /// [Pointer.fromFunction] only accepts static or top level functions. Use
  /// [NativeCallable.isolateLocal] to create callbacks from any Dart function
  /// or closure.
  external static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
    @DartRepresentationOf('T') Function f, [
    Object? exceptionalReturn,
  ]);

  /// Access to the raw pointer value.
  /// On 32-bit systems, the upper 32-bits of the result are 0.
  external int get address;

  /// Cast Pointer<T> to a Pointer<U>.
  external Pointer<U> cast<U extends NativeType>();

  /// Equality for Pointers only depends on their address.
  bool operator ==(Object other) {
    if (other is! Pointer) return false;
    Pointer otherPointer = other;
    return address == otherPointer.address;
  }

  /// The hash code for a Pointer only depends on its address.
  int get hashCode {
    return address.hashCode;
  }
}

/// A fixed-sized array of [T]s.
@Since('2.13')
final class Array<T extends NativeType> extends _Compound {
  /// Annotation to specify [Array] dimensions in [Struct]s.
  ///
  /// ```dart
  /// final class MyStruct extends Struct {
  ///   @Array(8)
  ///   external Array<Uint8> inlineArray;
  ///
  ///   @Array(2, 2, 2)
  ///   external Array<Array<Array<Uint8>>> threeDimensionalInlineArray;
  /// }
  /// ```
  ///
  /// Do not invoke in normal code.
  const factory Array(
    int dimension1, [
    int dimension2,
    int dimension3,
    int dimension4,
    int dimension5,
  ]) = _ArraySize<T>;

  /// Annotation to specify [Array] dimensions in [Struct]s.
  ///
  /// ```dart
  /// final class MyStruct extends Struct {
  ///   @Array.multi([2, 2, 2])
  ///   external Array<Array<Array<Uint8>>> threeDimensionalInlineArray;
  ///
  ///   @Array.multi([2, 2, 2, 2, 2, 2, 2, 2])
  ///   external Array<Array<Array<Array<Array<Array<Array<Array<Uint8>>>>>>>> eightDimensionalInlineArray;
  /// }
  /// ```
  ///
  /// Do not invoke in normal code.
  const factory Array.multi(List<int> dimensions) = _ArraySize<T>.multi;

  /// Annotation to specify a variable length [Array] in [Struct]s.
  ///
  /// Can only be used on the last field of a struct. The last field of the
  /// struct is _not_ taken into account in [sizeOf]. Using an
  /// [AllocatorAlloc.call] will _not_ allocate any backing storage for the
  /// variable length array. Instead use [Allocator.allocate] and calculate the
  /// required number of bytes manually.
  ///
  /// ```dart
  /// import 'dart:ffi';
  /// import 'package:ffi/ffi.dart';
  ///
  /// final class MyStruct extends Struct {
  ///   @Size()
  ///   external int length;
  ///
  ///   @Array.variable()
  ///   external Array<Uint8> inlineArray;
  ///
  ///   static Pointer<MyStruct> allocate(Allocator allocator, int length) {
  ///     final lengthInBytes = sizeOf<MyStruct>() + sizeOf<Uint8>() * length;
  ///     final result = allocator.allocate<MyStruct>(lengthInBytes);
  ///     result.ref.length = length;
  ///     return result;
  ///   }
  /// }
  ///
  /// void main() {
  ///   final myStruct = MyStruct.allocate(calloc, 10);
  /// }
  /// ```
  ///
  /// The variable length is always the outermost dimension of the array.
  ///
  /// ```dart
  /// import 'dart:ffi';
  /// import 'package:ffi/ffi.dart';
  ///
  /// final class MyStruct extends Struct {
  ///   @Size()
  ///   external int length;
  ///
  ///   @Array.variable(10, 10)
  ///   external Array<Array<Array<Uint8>>> inlineArray;
  ///
  ///   static Pointer<MyStruct> allocate(Allocator allocator, int length) {
  ///     final lengthInBytes = sizeOf<MyStruct>() + sizeOf<Uint8>() * length * 100;
  ///     final result = allocator.allocate<MyStruct>(lengthInBytes);
  ///     result.ref.length = length;
  ///     return result;
  ///   }
  /// }
  /// ```
  ///
  /// Accessing variable length inline arrays of structs passed by value in FFI
  /// calls and callbacks is undefined behavior. Accessing variable length
  /// inline arrays in structs passed by value is undefined behavior in C.
  ///
  /// For more information about variable length inline arrays in C, please
  /// refer to: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html.
  ///
  /// Do not invoke in normal code.
  @Since('3.6')
  const factory Array.variable([
    int dimension2,
    int dimension3,
    int dimension4,
    int dimension5,
  ]) = _ArraySize<T>.variable;

  /// Annotation to specify a variable length [Array] with a configurable
  /// variable dimension ([dimension1]) in [Struct]s.
  ///
  /// Can only be used on the last field of a struct. When [dimension1] is set
  /// to a value greater than zero (`0`), the last field of the struct is taken
  /// into account in [sizeOf] and [AllocatorAlloc.call]. This is particularly
  /// useful when working with Windows APIs, where most structs with variable
  /// length arrays are defined to have an initial dimension of one (`1`).
  ///
  /// ```dart
  /// import 'dart:ffi';
  /// import 'package:ffi/ffi.dart';
  ///
  /// final class MyStruct extends Struct {
  ///   @Size()
  ///   external int length;
  ///
  ///   @Array.variableWithVariableDimension(1)
  ///   external Array<Uint8> inlineArray;
  ///
  ///   static Pointer<MyStruct> allocate(Allocator allocator, int length) {
  ///     final lengthInBytes = sizeOf<MyStruct>() + sizeOf<Uint8>() * (length - 1);
  ///     final result = allocator.allocate<MyStruct>(lengthInBytes);
  ///     result.ref.length = length;
  ///     return result;
  ///   }
  /// }
  ///
  /// void main() {
  ///   final myStruct = MyStruct.allocate(calloc, 10);
  /// }
  /// ```
  ///
  /// The variable length is always the outermost dimension of the array.
  ///
  /// Do not invoke in normal code.
  @Since('3.7')
  const factory Array.variableWithVariableDimension([
    int dimension1,
    int dimension2,
    int dimension3,
    int dimension4,
    int dimension5,
  ]) = _ArraySize<T>.variableWithVariableDimension;

  /// Annotation to a variable length [Array] in [Struct]s.
  ///
  /// ```dart
  /// final class MyStruct extends Struct {
  ///   @Array.variableMulti([2, 2])
  ///   external Array<Array<Array<Uint8>>> threeDimensionalInlineArray;
  /// }
  ///
  /// final class MyStruct2 extends Struct {
  ///   @Array.variableMulti(variableDimension: 1, [2, 2, 2])
  ///   external Array<Array<Array<Array<Uint8>>>> fourDimensionalInlineArray;
  /// }
  ///
  /// final class MyStruct3 extends Struct {
  ///   @Array.variableMulti([2, 2, 2, 2, 2, 2, 2])
  ///   external Array<Array<Array<Array<Array<Array<Array<Array<Uint8>>>>>>>> eightDimensionalInlineArray;
  /// }
  /// ```
  ///
  /// The variable length is always the outermost dimension of the array.
  ///
  /// [variableDimension] is the outermost dimension of the variable length
  /// array (defaults to zero (`0`)). When [variableDimension] is set to a value
  /// greater than zero (`0`), the last field of the struct is taken into
  /// account in [sizeOf] and [AllocatorAlloc.call].
  ///
  /// Do not invoke in normal code.
  @Since('3.6')
  const factory Array.variableMulti(
    List<int> dimensions, {
    @Since('3.7') int variableDimension,
  }) = _ArraySize<T>.variableMulti;
}

final class _ArraySize<T extends NativeType> implements Array<T> {
  final int? dimension1;
  final int? dimension2;
  final int? dimension3;
  final int? dimension4;
  final int? dimension5;

  final List<int>? dimensions;

  // When non-null, [dimension1] is equal to this value, or [dimensions] should
  // be prepended with this value.
  final int? variableDimension;

  const _ArraySize(
    this.dimension1, [
    this.dimension2,
    this.dimension3,
    this.dimension4,
    this.dimension5,
  ]) : dimensions = null,
       variableDimension = null;

  const _ArraySize.multi(this.dimensions)
    : dimension1 = null,
      dimension2 = null,
      dimension3 = null,
      dimension4 = null,
      dimension5 = null,
      variableDimension = null;

  const _ArraySize.variable([
    this.dimension2,
    this.dimension3,
    this.dimension4,
    this.dimension5,
  ]) : dimension1 = 0,
       dimensions = null,
       variableDimension = 0;

  const _ArraySize.variableWithVariableDimension([
    this.dimension1,
    this.dimension2,
    this.dimension3,
    this.dimension4,
    this.dimension5,
  ]) : dimensions = null,
       variableDimension = dimension1;

  const _ArraySize.variableMulti(
    List<int> nestedDimensions, {
    int variableDimension = 0,
  }) : // Should be `[variableDimension, ...nestedDimensions]`.
       dimensions = nestedDimensions,
       dimension1 = null,
       dimension2 = null,
       dimension3 = null,
       dimension4 = null,
       dimension5 = null,
       variableDimension = variableDimension;
}

/// Extension on [Pointer] specialized for the type argument [NativeFunction].
extension NativeFunctionPointer<NF extends Function>
    on Pointer<NativeFunction<NF>> {
  /// Convert to Dart function, automatically marshalling the arguments and
  /// return value.
  ///
  /// [isLeaf] specifies whether the function is a leaf function. Leaf functions
  /// are small, short-running, non-blocking functions which are not allowed to
  /// call back into Dart or use any Dart VM APIs. Leaf functions are invoked
  /// bypassing some of the heavier parts of the standard Dart-to-Native calling
  /// sequence which reduces the invocation overhead, making leaf calls faster
  /// than non-leaf calls. However, this implies that a thread executing a leaf
  /// function can't cooperate with the Dart runtime. A long running or blocking
  /// leaf function will delay any operation which requires synchronization
  /// between all threads associated with an isolate group until after the leaf
  /// function returns. For example, if one isolate in a group is trying to
  /// perform a GC and a second isolate is blocked in a leaf call, then the
  /// first isolate will have to pause and wait until this leaf call returns.
  external DF asFunction<@DartRepresentationOf('NF') DF extends Function>({
    bool isLeaf = false,
  });
}

/// A native callable which listens for calls to a native function.
///
/// Creates a native function linked to a Dart function, so that calling the
/// native function will call the Dart function in some way, with the arguments
/// converted to Dart values.
@Since('3.1')
abstract final class NativeCallable<T extends Function> {
  /// Constructs a [NativeCallable] that must be invoked from the same thread
  /// that created it.
  ///
  /// If an exception is thrown by the [callback], the native function will
  /// return the `exceptionalReturn`, which must be assignable to the return
  /// type of the [callback].
  ///
  /// The returned function address can only be invoked on the mutator (main)
  /// thread of the current isolate. It will abort the process if invoked on any
  /// other thread. Use [NativeCallable.listener] to create callbacks that can
  /// be invoked from any thread.
  ///
  /// Unlike [Pointer.fromFunction], [NativeCallable]s can be constructed from
  /// any Dart function or closure, not just static or top level functions.
  ///
  /// This callback must be [close]d when it is no longer needed. The [Isolate]
  /// that created the callback will be kept alive until [close] is called.
  /// After [NativeCallable.close] is called, invoking the [nativeFunction] from
  /// native code will cause undefined behavior.
  factory NativeCallable.isolateLocal(
    @DartRepresentationOf("T") Function callback, {
    Object? exceptionalReturn,
  }) {
    throw UnsupportedError("NativeCallable cannot be constructed dynamically.");
  }

  /// Constructs a [NativeCallable] that can be invoked from any thread.
  ///
  /// When the native code invokes the function [nativeFunction], the arguments
  /// will be sent over a [SendPort] to the [Isolate] that created the
  /// [NativeCallable], and the callback will be invoked.
  ///
  /// The native code does not wait for a response from the callback, so only
  /// functions returning void are supported.
  ///
  /// The callback will be invoked at some time in the future. The native caller
  /// cannot assume the callback will be run immediately. Resources passed to
  /// the callback (such as pointers to malloc'd memory, or output parameters)
  /// must be valid until the call completes.
  ///
  /// This callback must be [close]d when it is no longer needed. The [Isolate]
  /// that created the callback will be kept alive until [close] is called.
  /// After [NativeCallable.close] is called, invoking the [nativeFunction] from
  /// native code will cause undefined behavior.
  ///
  /// For example:
  ///
  /// ```dart
  /// import 'dart:async';
  /// import 'dart:ffi';
  /// import 'package:ffi/ffi.dart';
  ///
  /// // Processes a simple HTTP GET request using a native HTTP library that
  /// // processes the request on a background thread.
  /// Future<String> httpGet(String uri) async {
  ///   final uriPointer = uri.toNativeUtf8();
  ///
  ///   // Create the NativeCallable.listener.
  ///   final completer = Completer<String>();
  ///   late final NativeCallable<NativeHttpCallback> callback;
  ///   void onResponse(Pointer<Utf8> responsePointer) {
  ///     completer.complete(responsePointer.toDartString());
  ///     calloc.free(responsePointer);
  ///     calloc.free(uriPointer);
  ///
  ///     // Remember to close the NativeCallable once the native API is
  ///     // finished with it, otherwise this isolate will stay alive
  ///     // indefinitely.
  ///     callback.close();
  ///   }
  ///   callback = NativeCallable<NativeHttpCallback>.listener(onResponse);
  ///
  ///   // Invoke the native HTTP API. Our example HTTP library processes our
  ///   // request on a background thread, and calls the callback on that same
  ///   // thread when it receives the response.
  ///   nativeHttpGet(uriPointer, callback.nativeFunction);
  ///
  ///   return completer.future;
  /// }
  ///
  /// // Load the native functions from a DynamicLibrary.
  /// final DynamicLibrary dylib = DynamicLibrary.process();
  /// typedef NativeHttpCallback = Void Function(Pointer<Utf8>);
  ///
  /// typedef HttpGetFunction = void Function(
  ///     Pointer<Utf8>, Pointer<NativeFunction<NativeHttpCallback>>);
  /// typedef HttpGetNativeFunction = Void Function(
  ///     Pointer<Utf8>, Pointer<NativeFunction<NativeHttpCallback>>);
  /// final nativeHttpGet =
  ///     dylib.lookupFunction<HttpGetNativeFunction, HttpGetFunction>(
  ///         'http_get');
  /// ```
  factory NativeCallable.listener(
    @DartRepresentationOf("T") Function callback,
  ) {
    throw UnsupportedError("NativeCallable cannot be constructed dynamically.");
  }

  /// The native function pointer which can be used to invoke the `callback`
  /// passed to the constructor.
  ///
  /// This pointer must not be read after the callable has been [close]d.
  Pointer<NativeFunction<T>> get nativeFunction;

  /// Closes this callback and releases its resources.
  ///
  /// Further calls to existing [nativeFunction]s will result in undefined
  /// behavior.
  ///
  /// Subsequent calls to [close] will be ignored.
  ///
  /// It is safe to call [close] inside the [callback].
  void close();

  /// Whether this [NativeCallable] keeps its [Isolate] alive.
  ///
  /// By default, [NativeCallable]s keep the [Isolate] that created them alive
  /// until [close] is called. If [keepIsolateAlive] is set to `false`, the
  /// isolate may exit even if the [NativeCallable] isn't closed.
  external bool keepIsolateAlive;
}

//
// The following code is generated, do not edit by hand.
//
// Code generated by `runtime/tools/ffi/sdk_lib_ffi_generator.dart`.
//

/// Extension on [Pointer] specialized for the type argument [Int8].
extension Int8Pointer on Pointer<Int8> {
  /// The 8-bit two's complement integer at [address].
  ///
  /// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before
  /// being stored, and the 8-bit value is sign-extended when it is loaded.
  external int get value;

  external void set value(int value);

  /// The 8-bit two's complement integer at `address + sizeOf<Int8>() * index`.
  ///
  /// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before
  /// being stored, and the 8-bit value is sign-extended when it is loaded.
  external int operator [](int index);

  /// The 8-bit two's complement integer at `address + sizeOf<Int8>() * index`.
  ///
  /// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before
  /// being stored, and the 8-bit value is sign-extended when it is loaded.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Int8> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Int8>() * index);

  /// A pointer to the [offset]th [Int8] after this one.
  ///
  /// Returns a pointer to the [Int8] whose address is
  /// [offset] times the size of `Int8` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Int8>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Int8> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Int8>() * offset);

  /// A pointer to the [offset]th [Int8] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Int8] whose address is
  /// [offset] times the size of `Int8` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Int8>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Int8> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Int8>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Int8>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  external Int8List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Int16].
extension Int16Pointer on Pointer<Int16> {
  /// The 16-bit two's complement integer at [address].
  ///
  /// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before
  /// being stored, and the 16-bit value is sign-extended when it is loaded.
  ///
  /// The [address] must be 2-byte aligned.
  external int get value;

  external void set value(int value);

  /// The 16-bit two's complement integer at `address + sizeOf<Int16>() * index`.
  ///
  /// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before
  /// being stored, and the 16-bit value is sign-extended when it is loaded.
  ///
  /// The [address] must be 2-byte aligned.
  external int operator [](int index);

  /// The 16-bit two's complement integer at `address + sizeOf<Int16>() * index`.
  ///
  /// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before
  /// being stored, and the 16-bit value is sign-extended when it is loaded.
  ///
  /// The [address] must be 2-byte aligned.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Int16> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Int16>() * index);

  /// A pointer to the [offset]th [Int16] after this one.
  ///
  /// Returns a pointer to the [Int16] whose address is
  /// [offset] times the size of `Int16` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Int16>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Int16> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Int16>() * offset);

  /// A pointer to the [offset]th [Int16] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Int16] whose address is
  /// [offset] times the size of `Int16` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Int16>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Int16> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Int16>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Int16>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  ///
  /// The [address] must be 2-byte aligned.
  external Int16List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Int32].
extension Int32Pointer on Pointer<Int32> {
  /// The 32-bit two's complement integer at [address].
  ///
  /// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before
  /// being stored, and the 32-bit value is sign-extended when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external int get value;

  external void set value(int value);

  /// The 32-bit two's complement integer at `address + sizeOf<Int32>() * index`.
  ///
  /// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before
  /// being stored, and the 32-bit value is sign-extended when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external int operator [](int index);

  /// The 32-bit two's complement integer at `address + sizeOf<Int32>() * index`.
  ///
  /// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before
  /// being stored, and the 32-bit value is sign-extended when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Int32> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Int32>() * index);

  /// A pointer to the [offset]th [Int32] after this one.
  ///
  /// Returns a pointer to the [Int32] whose address is
  /// [offset] times the size of `Int32` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Int32>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Int32> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Int32>() * offset);

  /// A pointer to the [offset]th [Int32] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Int32] whose address is
  /// [offset] times the size of `Int32` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Int32>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Int32> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Int32>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Int32>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  ///
  /// The [address] must be 4-byte aligned.
  external Int32List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Int64].
extension Int64Pointer on Pointer<Int64> {
  /// The 64-bit two's complement integer at [address].
  ///
  /// The [address] must be 8-byte aligned.
  external int get value;

  external void set value(int value);

  /// The 64-bit two's complement integer at `address + sizeOf<Int64>() * index`.
  ///
  /// The [address] must be 8-byte aligned.
  external int operator [](int index);

  /// The 64-bit two's complement integer at `address + sizeOf<Int64>() * index`.
  ///
  /// The [address] must be 8-byte aligned.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Int64> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Int64>() * index);

  /// A pointer to the [offset]th [Int64] after this one.
  ///
  /// Returns a pointer to the [Int64] whose address is
  /// [offset] times the size of `Int64` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Int64>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Int64> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Int64>() * offset);

  /// A pointer to the [offset]th [Int64] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Int64] whose address is
  /// [offset] times the size of `Int64` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Int64>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Int64> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Int64>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Int64>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  ///
  /// The [address] must be 8-byte aligned.
  external Int64List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Uint8].
extension Uint8Pointer on Pointer<Uint8> {
  /// The 8-bit unsigned integer at [address].
  ///
  /// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before
  /// being stored, and the 8-bit value is zero-extended when it is loaded.
  external int get value;

  external void set value(int value);

  /// The 8-bit unsigned integer at `address + sizeOf<Uint8>() * index`.
  ///
  /// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before
  /// being stored, and the 8-bit value is zero-extended when it is loaded.
  external int operator [](int index);

  /// The 8-bit unsigned integer at `address + sizeOf<Uint8>() * index`.
  ///
  /// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before
  /// being stored, and the 8-bit value is zero-extended when it is loaded.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Uint8> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Uint8>() * index);

  /// A pointer to the [offset]th [Uint8] after this one.
  ///
  /// Returns a pointer to the [Uint8] whose address is
  /// [offset] times the size of `Uint8` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Uint8>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Uint8> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Uint8>() * offset);

  /// A pointer to the [offset]th [Uint8] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Uint8] whose address is
  /// [offset] times the size of `Uint8` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Uint8>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Uint8> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Uint8>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Uint8>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  external Uint8List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Uint16].
extension Uint16Pointer on Pointer<Uint16> {
  /// The 16-bit unsigned integer at [address].
  ///
  /// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before
  /// being stored, and the 16-bit value is zero-extended when it is loaded.
  ///
  /// The [address] must be 2-byte aligned.
  external int get value;

  external void set value(int value);

  /// The 16-bit unsigned integer at `address + sizeOf<Uint16>() * index`.
  ///
  /// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before
  /// being stored, and the 16-bit value is zero-extended when it is loaded.
  ///
  /// The [address] must be 2-byte aligned.
  external int operator [](int index);

  /// The 16-bit unsigned integer at `address + sizeOf<Uint16>() * index`.
  ///
  /// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before
  /// being stored, and the 16-bit value is zero-extended when it is loaded.
  ///
  /// The [address] must be 2-byte aligned.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Uint16> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Uint16>() * index);

  /// A pointer to the [offset]th [Uint16] after this one.
  ///
  /// Returns a pointer to the [Uint16] whose address is
  /// [offset] times the size of `Uint16` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Uint16>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Uint16> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Uint16>() * offset);

  /// A pointer to the [offset]th [Uint16] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Uint16] whose address is
  /// [offset] times the size of `Uint16` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Uint16>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Uint16> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Uint16>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Uint16>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  ///
  /// The [address] must be 2-byte aligned.
  external Uint16List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Uint32].
extension Uint32Pointer on Pointer<Uint32> {
  /// The 32-bit unsigned integer at [address].
  ///
  /// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before
  /// being stored, and the 32-bit value is zero-extended when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external int get value;

  external void set value(int value);

  /// The 32-bit unsigned integer at `address + sizeOf<Uint32>() * index`.
  ///
  /// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before
  /// being stored, and the 32-bit value is zero-extended when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external int operator [](int index);

  /// The 32-bit unsigned integer at `address + sizeOf<Uint32>() * index`.
  ///
  /// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before
  /// being stored, and the 32-bit value is zero-extended when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Uint32> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Uint32>() * index);

  /// A pointer to the [offset]th [Uint32] after this one.
  ///
  /// Returns a pointer to the [Uint32] whose address is
  /// [offset] times the size of `Uint32` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Uint32>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Uint32> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Uint32>() * offset);

  /// A pointer to the [offset]th [Uint32] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Uint32] whose address is
  /// [offset] times the size of `Uint32` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Uint32>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Uint32> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Uint32>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Uint32>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  ///
  /// The [address] must be 4-byte aligned.
  external Uint32List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Uint64].
extension Uint64Pointer on Pointer<Uint64> {
  /// The 64-bit unsigned integer at [address].
  ///
  /// The [address] must be 8-byte aligned.
  external int get value;

  external void set value(int value);

  /// The 64-bit unsigned integer at `address + sizeOf<Uint64>() * index`.
  ///
  /// The [address] must be 8-byte aligned.
  external int operator [](int index);

  /// The 64-bit unsigned integer at `address + sizeOf<Uint64>() * index`.
  ///
  /// The [address] must be 8-byte aligned.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Uint64> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Uint64>() * index);

  /// A pointer to the [offset]th [Uint64] after this one.
  ///
  /// Returns a pointer to the [Uint64] whose address is
  /// [offset] times the size of `Uint64` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Uint64>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Uint64> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Uint64>() * offset);

  /// A pointer to the [offset]th [Uint64] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Uint64] whose address is
  /// [offset] times the size of `Uint64` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Uint64>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Uint64> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Uint64>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Uint64>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  ///
  /// The [address] must be 8-byte aligned.
  external Uint64List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Float].
extension FloatPointer on Pointer<Float> {
  /// The float at [address].
  ///
  /// A Dart double loses precision before being stored, and the float value is
  /// converted to a double when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external double get value;

  external void set value(double value);

  /// The float at `address + sizeOf<Float>() * index`.
  ///
  /// A Dart double loses precision before being stored, and the float value is
  /// converted to a double when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external double operator [](int index);

  /// The float at `address + sizeOf<Float>() * index`.
  ///
  /// A Dart double loses precision before being stored, and the float value is
  /// converted to a double when it is loaded.
  ///
  /// The [address] must be 4-byte aligned.
  external void operator []=(int index, double value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Float> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Float>() * index);

  /// A pointer to the [offset]th [Float] after this one.
  ///
  /// Returns a pointer to the [Float] whose address is
  /// [offset] times the size of `Float` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Float>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Float> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Float>() * offset);

  /// A pointer to the [offset]th [Float] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Float] whose address is
  /// [offset] times the size of `Float` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Float>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Float> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Float>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Float>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  ///
  /// The [address] must be 4-byte aligned.
  external Float32List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Double].
extension DoublePointer on Pointer<Double> {
  /// The double at [address].
  ///
  /// The [address] must be 8-byte aligned.
  external double get value;

  external void set value(double value);

  /// The double at `address + sizeOf<Double>() * index`.
  ///
  /// The [address] must be 8-byte aligned.
  external double operator [](int index);

  /// The double at `address + sizeOf<Double>() * index`.
  ///
  /// The [address] must be 8-byte aligned.
  external void operator []=(int index, double value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Double> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Double>() * index);

  /// A pointer to the [offset]th [Double] after this one.
  ///
  /// Returns a pointer to the [Double] whose address is
  /// [offset] times the size of `Double` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Double>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Double> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Double>() * offset);

  /// A pointer to the [offset]th [Double] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Double] whose address is
  /// [offset] times the size of `Double` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Double>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Double> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Double>() * offset);

  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from [address]
  /// to `address + sizeOf<Double>() * length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  ///
  /// If provided, [finalizer] will be run on the pointer once the typed list
  /// is GCed. If provided, [token] will be passed to [finalizer], otherwise
  /// the this pointer itself will be passed.
  ///
  /// The [address] must be 8-byte aligned.
  external Float64List asTypedList(
    int length, {
    @Since('3.1') Pointer<NativeFinalizerFunction>? finalizer,
    @Since('3.1') Pointer<Void>? token,
  });
}

/// Extension on [Pointer] specialized for the type argument [Bool].
@Since('2.15')
extension BoolPointer on Pointer<Bool> {
  /// The bool at [address].
  external bool get value;

  external void set value(bool value);

  /// The bool at `address + sizeOf<Bool>() * index`.
  external bool operator [](int index);

  /// The bool at `address + sizeOf<Bool>() * index`.
  external void operator []=(int index, bool value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  Pointer<Bool> elementAt(int index) =>
      Pointer.fromAddress(address + sizeOf<Bool>() * index);

  /// A pointer to the [offset]th [Bool] after this one.
  ///
  /// Returns a pointer to the [Bool] whose address is
  /// [offset] times the size of `Bool` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Bool>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Bool> operator +(int offset) =>
      Pointer.fromAddress(address + sizeOf<Bool>() * offset);

  /// A pointer to the [offset]th [Bool] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Bool] whose address is
  /// [offset] times the size of `Bool` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Bool>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  @Since('3.3')
  @pragma("vm:prefer-inline")
  Pointer<Bool> operator -(int offset) =>
      Pointer.fromAddress(address - sizeOf<Bool>() * offset);
}

/// Bounds checking indexing methods on [Array]s of [Int8].
@Since('2.13')
extension Int8Array on Array<Int8> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

/// Bounds checking indexing methods on [Array]s of [Int16].
@Since('2.13')
extension Int16Array on Array<Int16> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

/// Bounds checking indexing methods on [Array]s of [Int32].
@Since('2.13')
extension Int32Array on Array<Int32> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

/// Bounds checking indexing methods on [Array]s of [Int64].
@Since('2.13')
extension Int64Array on Array<Int64> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

/// Bounds checking indexing methods on [Array]s of [Uint8].
@Since('2.13')
extension Uint8Array on Array<Uint8> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

/// Bounds checking indexing methods on [Array]s of [Uint16].
@Since('2.13')
extension Uint16Array on Array<Uint16> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

/// Bounds checking indexing methods on [Array]s of [Uint32].
@Since('2.13')
extension Uint32Array on Array<Uint32> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

/// Bounds checking indexing methods on [Array]s of [Uint64].
@Since('2.13')
extension Uint64Array on Array<Uint64> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

/// Bounds checking indexing methods on [Array]s of [Float].
@Since('2.13')
extension FloatArray on Array<Float> {
  external double operator [](int index);

  external void operator []=(int index, double value);
}

/// Bounds checking indexing methods on [Array]s of [Double].
@Since('2.13')
extension DoubleArray on Array<Double> {
  external double operator [](int index);

  external void operator []=(int index, double value);
}

/// Bounds checking indexing methods on [Array]s of [Bool].
@Since('2.15')
extension BoolArray on Array<Bool> {
  external bool operator [](int index);

  external void operator []=(int index, bool value);
}

@Since('3.5')
extension Int8ListAddress on Int8List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Int8>)>(isLeaf: true)
  /// external void myFunction(Pointer<Int8> pointer);
  ///
  /// void main() {
  ///   final list = Int8List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Int8> get address;
}

@Since('3.5')
extension Int16ListAddress on Int16List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Int16>)>(isLeaf: true)
  /// external void myFunction(Pointer<Int16> pointer);
  ///
  /// void main() {
  ///   final list = Int16List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Int16> get address;
}

@Since('3.5')
extension Int32ListAddress on Int32List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Int32>)>(isLeaf: true)
  /// external void myFunction(Pointer<Int32> pointer);
  ///
  /// void main() {
  ///   final list = Int32List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Int32> get address;
}

@Since('3.5')
extension Int64ListAddress on Int64List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Int64>)>(isLeaf: true)
  /// external void myFunction(Pointer<Int64> pointer);
  ///
  /// void main() {
  ///   final list = Int64List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Int64> get address;
}

@Since('3.5')
extension Uint8ListAddress on Uint8List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Uint8>)>(isLeaf: true)
  /// external void myFunction(Pointer<Uint8> pointer);
  ///
  /// void main() {
  ///   final list = Uint8List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Uint8> get address;
}

@Since('3.5')
extension Uint16ListAddress on Uint16List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Uint16>)>(isLeaf: true)
  /// external void myFunction(Pointer<Uint16> pointer);
  ///
  /// void main() {
  ///   final list = Uint16List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Uint16> get address;
}

@Since('3.5')
extension Uint32ListAddress on Uint32List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Uint32>)>(isLeaf: true)
  /// external void myFunction(Pointer<Uint32> pointer);
  ///
  /// void main() {
  ///   final list = Uint32List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Uint32> get address;
}

@Since('3.5')
extension Uint64ListAddress on Uint64List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Uint64>)>(isLeaf: true)
  /// external void myFunction(Pointer<Uint64> pointer);
  ///
  /// void main() {
  ///   final list = Uint64List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Uint64> get address;
}

@Since('3.5')
extension Float32ListAddress on Float32List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Float>)>(isLeaf: true)
  /// external void myFunction(Pointer<Float> pointer);
  ///
  /// void main() {
  ///   final list = Float32List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Float> get address;
}

@Since('3.5')
extension Float64ListAddress on Float64List {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address`
  /// can only occurr as an entire argument expression in the invocation of
  /// a leaf [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Double>)>(isLeaf: true)
  /// external void myFunction(Pointer<Double> pointer);
  ///
  /// void main() {
  ///   final list = Float64List(10);
  ///   myFunction(list.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Double> get address;
}

//
// End of generated code.
//

/// Extension on [Pointer] specialized for the type argument [Pointer].
extension PointerPointer<T extends NativeType> on Pointer<Pointer<T>> {
  /// The pointer at [address].
  ///
  /// A [Pointer] is unboxed before being stored (as if by `.address`), and the
  /// pointer is boxed (as if by `Pointer.fromAddress`) when loaded.
  ///
  /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
  /// platforms the [address] must be 8-byte aligned.
  external Pointer<T> get value;

  external void set value(Pointer<T> value);

  /// Load a Dart value from this location offset by [index].
  ///
  /// A [Pointer] is unboxed before being stored (as if by `.address`), and the
  /// pointer is boxed (as if by `Pointer.fromAddress`) when loaded.
  ///
  /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
  /// platforms the [address] must be 8-byte aligned.
  external Pointer<T> operator [](int index);

  /// Store a Dart value into this location offset by [index].
  ///
  /// A [Pointer] is unboxed before being stored (as if by `.address`), and the
  /// pointer is boxed (as if by [Pointer.fromAddress]) when loaded.
  ///
  /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
  /// platforms the [address] must be 8-byte aligned.
  external void operator []=(int index, Pointer<T> value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  external Pointer<Pointer<T>> elementAt(int index);

  /// A pointer to the [offset]th [Pointer<T>] after this one.
  ///
  /// Returns a pointer to the [Pointer<T>] whose address is
  /// [offset] times the size of `Pointer<T>` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<Pointer<T>>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  external Pointer<Pointer<T>> operator +(int offset);

  /// A pointer to the [offset]th [Pointer<T>] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [Pointer<T>] whose address is
  /// [offset] times the size of `Pointer<T>` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<Pointer<T>>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  external Pointer<Pointer<T>> operator -(int offset);
}

/// Extension on [Pointer] specialized for the type argument [Struct].
@Since('2.12')
extension StructPointer<T extends Struct> on Pointer<T> {
  /// A Dart view of the struct referenced by this pointer.
  ///
  /// Reading [ref] creates a reference accessing the fields of this struct
  /// backed by native memory at [address].
  /// The [address] must be aligned according to the struct alignment rules of
  /// the platform.
  ///
  /// Assigning to [ref] copies contents of the struct into the native memory
  /// starting at [address].
  ///
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  external T get ref;
  external set ref(T value);

  /// A Dart view of the struct referenced by this pointer.
  ///
  /// Creates a reference accessing the fields of this struct backed by native
  /// memory at [address].
  /// The [address] must be aligned according to the struct alignment rules of
  /// the platform.
  ///
  /// Attaches [finalizer] to the backing store of the struct. If provided,
  /// [token] will be passed to [finalizer], otherwise the pointer (`this`)
  /// itself will be passed.
  /// The pointer (`this`) must _not_ be used anymore if the struct is _not_
  /// guaranteed to be kept alive.
  /// Prefer doing any native calls with the pointer _before_ calling
  /// [refWithFinalizer].
  ///
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  @Since('3.7')
  external T refWithFinalizer(
    Pointer<NativeFinalizerFunction> finalizer, {
    Pointer<Void>? token,
  });

  /// Creates a reference to access the fields of this struct backed by native
  /// memory at `address + sizeOf<T>() * index`.
  ///
  /// The [address] must be aligned according to the struct alignment rules of
  /// the platform.
  ///
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  external T operator [](int index);

  /// Copies the [value] struct into native memory, starting at
  /// `address * sizeOf<T>() * index`.
  ///
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  external void operator []=(int index, T value);

  /// Pointer arithmetic (takes element size into account)
  @Deprecated('Use operator + instead')
  external Pointer<T> elementAt(int index);

  /// A pointer to the [offset]th [T] after this one.
  ///
  /// Returns a pointer to the [T] whose address is
  /// [offset] times the size of `T` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<T>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  external Pointer<T> operator +(int offset);

  /// A pointer to the [offset]th [T] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [T] whose address is
  /// [offset] times the size of `T` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<T>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  external Pointer<T> operator -(int offset);
}

/// Extension on [Pointer] specialized for the type argument [Union].
@Since('2.14')
extension UnionPointer<T extends Union> on Pointer<T> {
  /// A Dart view of the union referenced by this pointer.
  ///
  /// Reading [ref] creates a reference accessing the fields of this union
  /// backed by native memory at [address].
  /// The [address] must be aligned according to the union alignment rules of
  /// the platform.
  ///
  /// Assigning to [ref] copies contents of the union into the native memory
  /// starting at [address].
  ///
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  external T get ref;
  external set ref(T value);

  /// A Dart view of the union referenced by this pointer.
  ///
  /// Creates a reference accessing the fields of this union backed by native
  /// memory at [address].
  /// The [address] must be aligned according to the union alignment rules of
  /// the platform.
  ///
  /// Attaches [finalizer] to the backing store of the union. If provided,
  /// [token] will be passed to [finalizer], otherwise the pointer (`this`)
  /// itself will be passed.
  /// The pointer (`this`) must _not_ be used anymore if the union is _not_
  /// guaranteed to be kept alive.
  /// Prefer doing any native calls with the pointer _before_ calling
  /// [refWithFinalizer].
  ///
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  @Since('3.7')
  external T refWithFinalizer(
    Pointer<NativeFinalizerFunction> finalizer, {
    Pointer<Void>? token,
  });

  /// Creates a reference to access the fields of this union backed by native
  /// memory at `address + sizeOf<T>() * index`.
  ///
  /// The [address] must be aligned according to the union alignment rules of
  /// the platform.
  ///
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  external T operator [](int index);

  /// Copies the [value] union into native memory, starting at
  /// `address * sizeOf<T>() * index`.
  ///
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  external void operator []=(int index, T value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  external Pointer<T> elementAt(int index);

  /// A pointer to the [offset]th [T] after this one.
  ///
  /// Returns a pointer to the [T] whose address is
  /// [offset] times the size of `T` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<T>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  external Pointer<T> operator +(int offset);

  /// A pointer to the [offset]th [T] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [T] whose address is
  /// [offset] times the size of `T` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<T>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  external Pointer<T> operator -(int offset);
}

/// Extension on [Pointer] specialized for the type argument
/// [AbiSpecificInteger].
@Since('2.16')
extension AbiSpecificIntegerPointer<T extends AbiSpecificInteger>
    on Pointer<T> {
  /// The integer at [address].
  external int get value;

  external void set value(int value);

  /// The integer at `address + sizeOf<T>() * index`.
  external int operator [](int index);

  /// The integer at `address + sizeOf<T>() * index`.
  external void operator []=(int index, int value);

  /// Pointer arithmetic (takes element size into account).
  @Deprecated('Use operator + instead')
  external Pointer<T> elementAt(int index);

  /// A pointer to the [offset]th [T] after this one.
  ///
  /// Returns a pointer to the [T] whose address is
  /// [offset] times the size of `T` after the address of this pointer.
  /// That is `(this + offset).address == this.address + offset * sizeOf<T>()`.
  ///
  /// Also `(this + offset).value` is equivalent to `this[offset]`,
  /// and similarly for setting.
  external Pointer<T> operator +(int offset);

  /// A pointer to the [offset]th [T] before this one.
  ///
  /// Equivalent to `this + (-offset)`.
  ///
  /// Returns a pointer to the [T] whose address is
  /// [offset] times the size of `T` before the address of this pointer.
  /// That is, `(this - offset).address == this.address - offset * sizeOf<T>()`.
  ///
  /// Also, `(this - offset).value` is equivalent to `this[-offset]`,
  /// and similarly for setting,
  external Pointer<T> operator -(int offset);
}

/// Bounds checking indexing methods on [Array]s of [Pointer].
@Since('2.13')
extension PointerArray<T extends NativeType> on Array<Pointer<T>> {
  external Pointer<T> operator [](int index);

  external void operator []=(int index, Pointer<T> value);
}

/// Bounds checking indexing methods on [Array]s of [Struct].
@Since('2.13')
extension StructArray<T extends Struct> on Array<T> {
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  external T operator [](int index);
}

/// Bounds checking indexing methods on [Array]s of [Union].
@Since('2.14')
extension UnionArray<T extends Union> on Array<T> {
  /// This extension method must be invoked on a receiver of type `Pointer<T>`
  /// where `T` is a compile-time constant type.
  external T operator [](int index);
}

/// Bounds checking indexing methods on [Array]s of [Array].
@Since('2.13')
extension ArrayArray<T extends NativeType> on Array<Array<T>> {
  external Array<T> operator [](int index);

  external void operator []=(int index, Array<T> value);
}

/// Bounds checking indexing methods on [Array]s of [AbiSpecificInteger].
@Since('2.16')
extension AbiSpecificIntegerArray<T extends AbiSpecificInteger> on Array<T> {
  external int operator [](int index);

  external void operator []=(int index, int value);
}

@Since('3.5')
extension ArrayAddress<T extends NativeType> on Array<T> {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address` can
  /// only occurr as an entire argument expression in the invocation of a leaf
  /// [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart
  /// @Native<Void Function(Pointer<Int8>)>(isLeaf: true)
  /// external void myFunction(Pointer<Int8> pointer);
  ///
  /// final class MyStruct extends Struct {
  ///   @Array(10)
  ///   external Array<Int8> array;
  /// }
  ///
  /// void main() {
  ///   final array = Struct.create<MyStruct>().array;
  ///   myFunction(array.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<T> get address;
}

@Since('3.5')
extension StructAddress<T extends Struct> on T {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address` can
  /// only occurr as an entire argument expression in the invocation of a leaf
  /// [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart
  /// @Native<Void Function(Pointer<MyStruct>)>(isLeaf: true)
  /// external void myFunction(Pointer<MyStruct> pointer);
  ///
  /// final class MyStruct extends Struct {
  ///   @Int8()
  ///   external int x;
  /// }
  ///
  /// void main() {
  ///   final myStruct = Struct.create<MyStruct>();
  ///   myFunction(myStruct.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<T> get address;
}

@Since('3.5')
extension UnionAddress<T extends Union> on T {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address` can
  /// only occurr as an entire argument expression in the invocation of a leaf
  /// [Native] external function.
  ///
  /// Example:
  ///
  /// ```dart
  /// @Native<Void Function(Pointer<MyUnion>)>(isLeaf: true)
  /// external void myFunction(Pointer<MyUnion> pointer);
  ///
  /// final class MyUnion extends Union {
  ///   @Int8()
  ///   external int x;
  /// }
  ///
  /// void main() {
  ///   final myUnion = Union.create<MyUnion>();
  ///   myFunction(myUnion.address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<T> get address;
}

@Since('3.5')
extension IntAddress on int {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address` can
  /// only occurr as an entire argument expression in the invocation of a leaf
  /// [Native] external function.
  ///
  /// Can only be used on fields of [Struct] subtypes, fields of [Union]
  /// subtypes, [Array] elements, or [TypedData] elements. In other words, the
  /// number whose address is being accessed must itself be acccessed through a
  /// [Struct], [Union], [Array], or [TypedData].
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Int8>)>(isLeaf: true)
  /// external void myFunction(Pointer<Int8> pointer);
  ///
  /// final class MyStruct extends Struct {
  ///   @Int8()
  ///   external int x;
  ///
  ///   @Int8()
  ///   external int y;
  ///
  ///   @Array(10)
  ///   external Array<Int8> array;
  /// }
  ///
  /// void main() {
  ///   final myStruct = Struct.create<MyStruct>();
  ///   myFunction(myStruct.y.address);
  ///   myFunction(myStruct.array[5].address);
  ///
  ///   final list = Int8List(10);
  ///   myFunction(list[5].address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Never> address;
}

@Since('3.5')
extension DoubleAddress on double {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address` can
  /// only occurr as an entire argument expression in the invocation of a leaf
  /// [Native] external function.
  ///
  /// Can only be used on fields of [Struct] subtypes, fields of [Union]
  /// subtypes, [Array] elements, or [TypedData] elements. In other words, the
  /// number whose address is being accessed must itself be acccessed through a
  /// [Struct], [Union], [Array], or [TypedData].
  ///
  /// Example:
  ///
  /// ```dart import:typed_data
  /// @Native<Void Function(Pointer<Float>)>(isLeaf: true)
  /// external void myFunction(Pointer<Float> pointer);
  ///
  /// final class MyStruct extends Struct {
  ///   @Float()
  ///   external double x;
  ///
  ///   @Float()
  ///   external double y;
  ///
  ///   @Array(10)
  ///   external Array<Float> array;
  /// }
  ///
  /// void main() {
  ///   final myStruct = Struct.create<MyStruct>();
  ///   myFunction(myStruct.y.address);
  ///   myFunction(myStruct.array[5].address);
  ///
  ///   final list = Float32List(10);
  ///   myFunction(list[5].address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Never> address;
}

@Since('3.5')
extension BoolAddress on bool {
  /// The memory address of the underlying data.
  ///
  /// An expression of the form `expression.address` denoting this `address` can
  /// only occurr as an entire argument expression in the invocation of a leaf
  /// [Native] external function.
  ///
  /// Can only be used on fields of [Struct] subtypes, fields of [Union]
  /// subtypes, or [Array] elements. In other words, the boolean whose address
  /// is being accessed must itself be acccessed through a [Struct], [Union] or
  /// [Array].
  ///
  /// Example:
  ///
  /// ```dart
  /// @Native<Void Function(Pointer<Int8>)>(isLeaf: true)
  /// external void myFunction(Pointer<Int8> pointer);
  ///
  /// final class MyStruct extends Struct {
  ///   @Bool()
  ///   external bool x;
  ///
  ///   @Bool()
  ///   external bool y;
  ///
  ///   @Array(10)
  ///   external Array<Bool> array;
  /// }
  ///
  /// void main() {
  ///   final myStruct = Struct.create<MyStruct>();
  ///   myFunction(myStruct.y.address);
  ///   myFunction(myStruct.array[5].address);
  /// }
  /// ```
  ///
  /// The expression before `.address` is evaluated like the left-hand-side of
  /// an assignment, to something that gives access to the storage behind the
  /// expression, which can be used both for reading and writing. The `.address`
  /// then gives a native pointer to that storage.
  ///
  /// The `.address` is evaluated just before calling into native code when
  /// invoking a leaf [Native] external function. This ensures the Dart garbage
  /// collector will not move the object that the address points in to.
  external Pointer<Never> address;
}

/// Extension to retrieve the native `Dart_Port` from a [SendPort].
@Since('2.7')
extension NativePort on SendPort {
  /// The native port of this [SendPort].
  ///
  /// The returned native port can for example be used by C code to post
  /// messages to the connected [ReceivePort] via `Dart_PostCObject()` - see
  /// `dart_native_api.h`.
  ///
  /// Only the send ports from the platform classes [ReceivePort] and
  /// [RawReceivePort] are supported. User-defined implementations of
  /// [SendPort] are not supported.
  external int get nativePort;
}

/// Opaque, not exposing it's members.
@Since('2.8')
final class Dart_CObject extends Opaque {}

typedef Dart_NativeMessageHandler = Void Function(Int64, Pointer<Dart_CObject>);

/// Utilities for accessing the Dart VM API from Dart code or
/// from C code via `dart_api_dl.h`.
@Since('2.8')
abstract final class NativeApi {
  /// On breaking changes the major version is increased.
  ///
  /// The versioning covers the API surface in `dart_api_dl.h`.
  @Since('2.9')
  external static int get majorVersion;

  /// On backwards compatible changes the minor version is increased.
  ///
  /// The versioning covers the API surface in `dart_api_dl.h`.
  @Since('2.9')
  external static int get minorVersion;

  /// A function pointer to
  /// `bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message)`
  /// in `dart_native_api.h`.
  external static Pointer<
    NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>
  >
  get postCObject;

  /// A function pointer to
  /// ```c
  /// Dart_Port Dart_NewNativePort(const char* name,
  ///                              Dart_NativeMessageHandler handler,
  ///                              bool handle_concurrently)
  /// ```
  /// in `dart_native_api.h`.
  external static Pointer<
    NativeFunction<
      Int64 Function(
        Pointer<Uint8>,
        Pointer<NativeFunction<Dart_NativeMessageHandler>>,
        Int8,
      )
    >
  >
  get newNativePort;

  /// A function pointer to
  /// `bool Dart_CloseNativePort(Dart_Port native_port_id)`
  /// in `dart_native_api.h`.
  external static Pointer<NativeFunction<Int8 Function(Int64)>>
  get closeNativePort;

  /// Pass this to `Dart_InitializeApiDL` in your native code to enable using the
  /// symbols in `dart_api_dl.h`.
  @Since('2.9')
  external static Pointer<Void> get initializeApiDLData;
}

/// Annotation binding an external declaration to its native implementation.
///
/// Can only be applied to `external` declarations of static and top-level
/// functions and variables.
///
/// A [Native]-annotated `external` function is implemented by native code.
/// The implementation is found in the native library denoted by [assetId].
/// Similarly, a [Native]-annotated `external` variable is implemented by
/// reading from or writing to native memory.
///
/// The compiler and/or runtime provides a binding from [assetId] to native
/// library, which depends on the target platform.
/// The compiler/runtime can then resolve/lookup symbols (identifiers)
/// against the native library, to find a native function or a native global
/// variable, and bind an `external` Dart function or variable declaration to
/// that native declaration.
/// By default, the runtime expects a native symbol with the same name as the
/// annotated function or variable in Dart. This can be overridden with the
/// [symbol] parameter on the annotation.
///
/// When used on a function, [T] must be a function type that represents the
/// native function's parameter and return types. The parameter and return types
/// must be subtypes of [NativeType].
///
/// When used on a variable, [T] must be a compatible native type. For example,
/// an [int] field can be annotated with [Int32].
///
/// If the type argument [T] is omitted in the `@Native` annotation, it is
/// inferred from the static type of the declaration, which must meet the
/// following constraints:
///
/// For function or method declarations:
/// - The return type must be one of the following:
///   - [Pointer]
///   - `void`
///   - Subtype of compound types, such as [Struct] or [Union]
/// - The parameter types must be subtypes of compound types or [Pointer]
///
/// For variable declarations, the type can be any of the following:
///   - [Pointer]
///   - Subtype of compound types, such as [Struct] or [Union]
///
/// For native global variables that cannot be reassigned, a `final` variable in
/// Dart or a getter can be used to prevent modifications to the native field.
///
/// Example:
///
/// ```dart template:top
/// @Native<Int64 Function(Int64, Int64)>()
/// external int sum(int a, int b);
///
/// @Native()
/// external void free(Pointer p);
///
/// @Native<Int64>()
/// external int aGlobalInt;
///
/// @Native()
/// external final Pointer<Char> aGlobalString;
/// ```
///
/// Calling a `@Native` function, as well as reading or writing to a `@Native`
/// variable, will try to resolve the [symbol] in (in the order):
/// 1. the provided or default [assetId],
/// 2. the native resolver set with `Dart_SetFfiNativeResolver` in
///    `dart_api.h`, and
/// 3. the current process.
///
/// At least one of those three *must* provide a binding for the symbol,
/// otherwise the method call or the variable access fails.
///
/// NOTE: This is an experimental feature and may change in the future.
@Since('2.19')
final class Native<T> {
  // Implementation note: VM hardcodes the layout of this class (number and
  // order of its fields), so adding/removing/changing fields requires
  // updating the VM code (see Function::GetNativeAnnotation()).

  /// The native symbol to be resolved, if not using the default.
  ///
  /// If not specified, the default symbol used for native function lookup
  /// is the annotated function's name.
  ///
  /// Example:
  ///
  /// ```dart template:top
  /// @Native<Int64 Function(Int64, Int64)>()
  /// external int sum(int a, int b);
  /// ```
  ///
  /// Example 2:
  ///
  /// ```dart template:top
  /// @Native<Int64 Function(Int64, Int64)>(symbol: 'sum')
  /// external int sum(int a, int b);
  /// ```
  ///
  /// The above two examples are equivalent.
  ///
  /// Prefer omitting the [symbol] when possible.
  final String? symbol;

  /// The ID of the asset in which [symbol] is resolved, if not using the
  /// default.
  ///
  /// If no asset name is specified, the default is to use an asset ID
  /// specified using an [DefaultAsset] annotation on the current library's
  /// `library` declaration, and if there is no [DefaultAsset] annotation on
  /// the current library, the library's URI (as a string) is used instead.
  ///
  /// Example (file `package:a/a.dart`):
  ///
  /// ```dart template:top
  /// @Native<Int64 Function(Int64, Int64)>()
  /// external int sum(int a, int b);
  /// ```
  ///
  /// Example 2 (file `package:a/a.dart`):
  ///
  /// ```dart template:none
  /// @DefaultAsset('package:a/a.dart')
  /// library a;
  ///
  /// import 'dart:ffi';
  ///
  /// @Native<Int64 Function(Int64, Int64)>()
  /// external int sum(int a, int b);
  /// ```
  ///
  /// Example 3 (file `package:a/a.dart`):
  ///
  /// ```dart template:top
  /// @Native<Int64 Function(Int64, Int64)>(assetId: 'package:a/a.dart')
  /// external int sum(int a, int b);
  /// ```
  ///
  /// The above three examples are all equivalent.
  ///
  /// Prefer using the library URI as an asset name over specifying it.
  /// Prefer using an [DefaultAsset] on the `library` declaration
  /// over specifying the asset name in a [Native] annotation.
  final String? assetId;

  /// Whether the function is a leaf function.
  ///
  /// Leaf functions are small, short-running, non-blocking functions which are
  /// not allowed to call back into Dart or use any Dart VM APIs. Leaf functions
  /// are invoked bypassing some of the heavier parts of the standard
  /// Dart-to-Native calling sequence which reduces the invocation overhead,
  /// making leaf calls faster than non-leaf calls. However, this implies that a
  /// thread executing a leaf function can't cooperate with the Dart runtime. A
  /// long running or blocking leaf function will delay any operation which
  /// requires synchronization between all threads associated with an isolate
  /// group until after the leaf function returns. For example, if one isolate
  /// in a group is trying to perform a GC and a second isolate is blocked in a
  /// leaf call, then the first isolate will have to pause and wait until this
  /// leaf call returns.
  ///
  /// This value has no meaning for native fields.
  final bool isLeaf;

  const Native({this.assetId, this.isLeaf = false, this.symbol});

  /// The native address of the implementation of [native].
  ///
  /// When calling this function, the argument for [native] must be an
  /// expression denoting a variable or function declaration which is annotated
  /// with [Native].
  /// For a variable declaration, the type [T] must be the same native type
  /// as the type argument to that `@Native` annotation.
  /// For a function declaration, the type [T] must be `NativeFunction<F>`
  /// where `F` was the type argument to that `@Native` annotation.
  ///
  /// For example, for a native C library exposing a function:
  ///
  /// ```C
  /// #include <stdint.h>
  /// int64_t sum(int64_t a, int64_t b) { return a + b; }
  /// ```
  ///
  /// The following code binds `sum` to a Dart function declaration, and
  /// extracts the address of the native `sum` implementation:
  ///
  /// ```dart
  /// import 'dart:ffi';
  ///
  /// typedef NativeAdd = Int64 Function(Int64, Int64);
  ///
  /// @Native<NativeAdd>()
  /// external int sum(int a, int b);
  ///
  /// void main() {
  ///   Pointer<NativeFunction<NativeAdd>> addressSum = Native.addressOf(sum);
  /// }
  /// ```
  ///
  /// Similarly, for a native C library exposing a global variable:
  ///
  /// ```C
  /// const char* myString;
  /// ```
  ///
  /// The following code binds `myString` to a top-level variable in Dart, and
  /// extracts the address of the underlying native field:
  ///
  /// ```dart
  /// import 'dart:ffi';
  ///
  /// @Native()
  /// external Pointer<Char> myString;
  ///
  /// void main() {
  ///   // This pointer points to the memory location where the loader has
  ///   // placed the `myString` global itself. To get the string value, read
  ///   // the myString field directly.
  ///   Pointer<Pointer<Char>> addressMyString = Native.addressOf(myString);
  /// }
  /// ```
  @Since('3.3')
  external static Pointer<T> addressOf<T extends NativeType>(
    @DartRepresentationOf('T') Object native,
  );
}

/// Annotation specifying the default asset ID for the current library.
///
/// The annotation applies only to `library` declarations.
///
/// The compiler and/or runtime provides a binding from _asset ID_ to native
/// library, which depends on the target platform and architecture.
/// The compiler/runtime can resolve identifiers (symbols)
/// against the native library, looking up native function implementations
/// which are then used as the implementation of `external` Dart function
/// declarations.
///
/// If used as annotation on a `library` declaration, all [Native]-annotated
/// external functions in this library will use the specified asset [id]
/// for native function resolution (unless overridden by [Native.assetId]).
///
/// If no [DefaultAsset] annotation is provided, the current library's URI
/// is the default asset ID for [Native]-annotated external functions.
///
/// Example (file `package:a/a.dart`):
///
/// ```dart template:top
/// @Native<Int64 Function(Int64, Int64)>()
/// external int sum(int a, int b);
/// ```
///
/// Example 2 (file `package:a/a.dart`):
///
/// ```dart template:none
/// @DefaultAsset('package:a/a.dart')
/// library a;
///
/// import 'dart:ffi';
///
/// @Native<Int64 Function(Int64, Int64)>()
/// external int sum(int a, int b);
/// ```
///
/// The above two examples are equivalent.
///
/// Prefer using the library URI as asset name when possible.
///
/// NOTE: This is an experimental feature and may change in the future.
@Since('2.19')
final class DefaultAsset {
  /// The default asset name for [Native] external functions in this library.
  final String id;

  const DefaultAsset(this.id);
}
