// ignore_for_file: unused_element
// ignore_for_file: unused_field

// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

class Bindings {
  /// Holds the symbol lookup function.
  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
      _lookup;

  /// The symbols are looked up in [dynamicLibrary].
  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;

  /// The symbols are looked up with [lookup].
  Bindings.fromLookup(
      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
          lookup)
      : _lookup = lookup;

  NamedFunctionProto func1(
    NamedFunctionProto named,
    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Int32)>> unnamed,
  ) {
    return _func1(
      named,
      unnamed,
    );
  }

  late final _func1_ptr = _lookup<
      ffi.NativeFunction<
          NamedFunctionProto Function(
              NamedFunctionProto,
              ffi.Pointer<
                  ffi.NativeFunction<ffi.Void Function(ffi.Int32)>>)>>('func1');
  late final _func1 = _func1_ptr.asFunction<
      NamedFunctionProto Function(NamedFunctionProto,
          ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Int32)>>)>();

  void func2(
    ffi.Pointer<NTyperef1> arg0,
  ) {
    return _func2(
      arg0,
    );
  }

  late final _func2_ptr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<NTyperef1>)>>(
          'func2');
  late final _func2 =
      _func2_ptr.asFunction<void Function(ffi.Pointer<NTyperef1>)>();

  void func3(
    int arg0,
    int b,
  ) {
    return _func3(
      arg0,
      b,
    );
  }

  late final _func3_ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.IntPtr, nesting_a_specified_type)>>('func3');
  late final _func3 = _func3_ptr.asFunction<void Function(int, int)>();

  bool func4(
    ffi.Pointer<ffi.Uint8> a,
  ) {
    return _func4(
          a,
        ) !=
        0;
  }

  late final _func4_ptr =
      _lookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Uint8>)>>(
          'func4');
  late final _func4 =
      _func4_ptr.asFunction<int Function(ffi.Pointer<ffi.Uint8>)>();
}

class Struct1 extends ffi.Struct {
  external NamedFunctionProto named;

  external ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> unnamed;
}

typedef NamedFunctionProto
    = ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>;

class AnonymousStructInTypedef extends ffi.Opaque {}

class _NamedStructInTypedef extends ffi.Opaque {}

typedef NTyperef1 = ExcludedStruct;
typedef ExcludedStruct = _ExcludedStruct;

class _ExcludedStruct extends ffi.Opaque {}

abstract class AnonymousEnumInTypedef {
  static const int a = 0;
}

abstract class _NamedEnumInTypedef {
  static const int b = 0;
}

typedef nesting_a_specified_type = ffi.IntPtr;

class Struct2 extends ffi.Opaque {}

class withBoolAlias extends ffi.Struct {
  @ffi.Uint8()
  external int b;
}
