// WARNING: This file is machine generated by fidlgen_dart.
// @dart = 2.12

library fidl_fidl_test_nullable_async;

import 'dart:async' as $async;
import 'dart:core' hide Set;
import 'dart:developer';
import 'dart:typed_data';

import 'package:fidl/fidl.dart' as $fidl;
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart' as $zircon;

import 'package:fidl_zx/fidl_async.dart' as lib$zx;
// ignore_for_file: always_specify_types
// ignore_for_file: avoid_positional_boolean_parameters
// ignore_for_file: avoid_returning_null
// ignore_for_file: cascade_invocations
// ignore_for_file: constant_identifier_names
// ignore_for_file: one_member_abstracts
// ignore_for_file: prefer_constructors_over_static_methods
// ignore_for_file: prefer_single_quotes
// ignore_for_file: public_member_api_docs
// ignore_for_file: unused_import
// ignore_for_file: unused_local_variable
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: library_prefixes
// ignore_for_file: prefer_typing_uninitialized_variables
// ignore_for_file: avoid_js_rounded_ints
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: prefer_generic_function_type_aliases
// ignore_for_file: prefer_equal_for_default_values
// ignore_for_file: avoid_catches_without_on_clauses
// ignore_for_file: unused_shown_name
// ignore_for_file: unnecessary_lambdas
// ignore_for_file: comment_references
// ignore_for_file: avoid_unused_constructor_parameters
// ignore_for_file: prefer_interpolation_to_compose_strings

enum SimpleUnionTag {
  a, // 0x1
  b, // 0x2
}

const Map<int, SimpleUnionTag> _SimpleUnionTag_map = {
  1: SimpleUnionTag.a,
  2: SimpleUnionTag.b,
};

class SimpleUnion extends $fidl.XUnion {
  const SimpleUnion.withA(int value)
      : _ordinal = 1,
        _data = value;

  const SimpleUnion.withB(double value)
      : _ordinal = 2,
        _data = value;

  SimpleUnion._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  SimpleUnionTag get $tag => _SimpleUnionTag_map[_ordinal]!;

  int? get a {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  double? get b {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'SimpleUnion.a(' + a.toString() + ')';
      case 2:
        return r'SimpleUnion.b(' + b.toString() + ')';
      default:
        return r'SimpleUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static SimpleUnion _ctor(int ordinal, Object data) {
    return SimpleUnion._(ordinal, data);
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<SimpleUnion> kSimpleUnion_Type =
    $fidl.UnionType<SimpleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.Float32Type(),
  },
  ctor: SimpleUnion._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<SimpleUnion> kSimpleUnion_OptType =
    $fidl.NullableUnionType<SimpleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.Float32Type(),
  },
  ctor: SimpleUnion._ctor,
  flexible: false,
  resource: false,
);

class StructWithNullableString extends $fidl.Struct {
  const StructWithNullableString({
    this.val,
  });
  StructWithNullableString.clone(
    StructWithNullableString $orig, {
    String? val,
  }) : this(
          val: val ?? $orig.val,
        );

  StructWithNullableString.cloneWithout(
    StructWithNullableString $orig, {
    bool val = false,
  }) : this(
          val: val ? null : $orig.val,
        );

  final String? val;

  @override
  List<Object?> get $fields {
    return <Object?>[
      val,
    ];
  }

  static const $fieldType0 = $fidl.NullableStringType(maybeElementCount: null);

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, val, $offset + 0, $depth);
  }

  @override
  String toString() {
    return r'StructWithNullableString' r'(val: ' + val.toString() + r')';
  }

  static StructWithNullableString _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return StructWithNullableString(
        val: $fieldType0.decode($decoder, $offset + 0, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithNullableString>
    kStructWithNullableString_Type = $fidl.StructType<StructWithNullableString>(
  inlineSize: 16,
  structDecode: StructWithNullableString._structDecode,
);

class StructWithNullableVector extends $fidl.Struct {
  const StructWithNullableVector({
    this.val,
  });
  StructWithNullableVector.clone(
    StructWithNullableVector $orig, {
    Int32List? val,
  }) : this(
          val: val ?? $orig.val,
        );

  StructWithNullableVector.cloneWithout(
    StructWithNullableVector $orig, {
    bool val = false,
  }) : this(
          val: val ? null : $orig.val,
        );

  final Int32List? val;

  @override
  List<Object?> get $fields {
    return <Object?>[
      val,
    ];
  }

  static const $fieldType0 = $fidl.NullableVectorType<int, Int32List>(
      element: $fidl.Int32Type(), maybeElementCount: null);

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, val, $offset + 0, $depth);
  }

  @override
  String toString() {
    return r'StructWithNullableVector' r'(val: ' + val.toString() + r')';
  }

  static StructWithNullableVector _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return StructWithNullableVector(
        val: $fieldType0.decode($decoder, $offset + 0, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithNullableVector>
    kStructWithNullableVector_Type = $fidl.StructType<StructWithNullableVector>(
  inlineSize: 16,
  structDecode: StructWithNullableVector._structDecode,
);

class StructWithNullableHandle extends $fidl.Struct {
  const StructWithNullableHandle({
    this.val,
  });
  StructWithNullableHandle.clone(
    StructWithNullableHandle $orig, {
    $zircon.Vmo? val,
  }) : this(
          val: val ?? $orig.val,
        );

  StructWithNullableHandle.cloneWithout(
    StructWithNullableHandle $orig, {
    bool val = false,
  }) : this(
          val: val ? null : $orig.val,
        );

  final $zircon.Vmo? val;

  @override
  List<Object?> get $fields {
    return <Object?>[
      val,
    ];
  }

  static const $fieldType0 = $fidl.NullableHandleType(
      $fidl.VmoType(objectType: 3, rights: 2147483648));

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, val, $offset + 0, $depth);
  }

  @override
  String toString() {
    return r'StructWithNullableHandle' r'(val: ' + val.toString() + r')';
  }

  static StructWithNullableHandle _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return StructWithNullableHandle(
        val: $fieldType0.decode($decoder, $offset + 0, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithNullableHandle>
    kStructWithNullableHandle_Type = $fidl.StructType<StructWithNullableHandle>(
  inlineSize: 4,
  structDecode: StructWithNullableHandle._structDecode,
);

class StructWithNullableProtocol extends $fidl.Struct {
  const StructWithNullableProtocol({
    this.val,
  });
  StructWithNullableProtocol.clone(
    StructWithNullableProtocol $orig, {
    $fidl.InterfaceHandle<SimpleProtocol>? val,
  }) : this(
          val: val ?? $orig.val,
        );

  StructWithNullableProtocol.cloneWithout(
    StructWithNullableProtocol $orig, {
    bool val = false,
  }) : this(
          val: val ? null : $orig.val,
        );

  final $fidl.InterfaceHandle<SimpleProtocol>? val;

  @override
  List<Object?> get $fields {
    return <Object?>[
      val,
    ];
  }

  static const $fieldType0 =
      $fidl.NullableInterfaceHandleType<SimpleProtocol>();

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, val, $offset + 0, $depth);
  }

  @override
  String toString() {
    return r'StructWithNullableProtocol' r'(val: ' + val.toString() + r')';
  }

  static StructWithNullableProtocol _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return StructWithNullableProtocol(
        val: $fieldType0.decode($decoder, $offset + 0, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithNullableProtocol>
    kStructWithNullableProtocol_Type =
    $fidl.StructType<StructWithNullableProtocol>(
  inlineSize: 4,
  structDecode: StructWithNullableProtocol._structDecode,
);

class StructWithNullableRequest extends $fidl.Struct {
  const StructWithNullableRequest({
    this.val,
  });
  StructWithNullableRequest.clone(
    StructWithNullableRequest $orig, {
    $fidl.InterfaceRequest<SimpleProtocol>? val,
  }) : this(
          val: val ?? $orig.val,
        );

  StructWithNullableRequest.cloneWithout(
    StructWithNullableRequest $orig, {
    bool val = false,
  }) : this(
          val: val ? null : $orig.val,
        );

  final $fidl.InterfaceRequest<SimpleProtocol>? val;

  @override
  List<Object?> get $fields {
    return <Object?>[
      val,
    ];
  }

  static const $fieldType0 =
      $fidl.NullableInterfaceRequestType<SimpleProtocol>();

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, val, $offset + 0, $depth);
  }

  @override
  String toString() {
    return r'StructWithNullableRequest' r'(val: ' + val.toString() + r')';
  }

  static StructWithNullableRequest _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return StructWithNullableRequest(
        val: $fieldType0.decode($decoder, $offset + 0, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithNullableRequest>
    kStructWithNullableRequest_Type =
    $fidl.StructType<StructWithNullableRequest>(
  inlineSize: 4,
  structDecode: StructWithNullableRequest._structDecode,
);

class Int32Wrapper extends $fidl.Struct {
  const Int32Wrapper({
    required this.val,
  });
  Int32Wrapper.clone(
    Int32Wrapper $orig, {
    int? val,
  }) : this(
          val: val ?? $orig.val,
        );

  final int val;

  @override
  List<Object?> get $fields {
    return <Object?>[
      val,
    ];
  }

  static const $fieldType0 = $fidl.Int32Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, val, $offset + 0, $depth);
  }

  @override
  String toString() {
    return r'Int32Wrapper' r'(val: ' + val.toString() + r')';
  }

  static Int32Wrapper _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return Int32Wrapper(val: $fieldType0.decode($decoder, $offset + 0, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Int32Wrapper> kInt32Wrapper_Type =
    $fidl.StructType<Int32Wrapper>(
  inlineSize: 4,
  structDecode: Int32Wrapper._structDecode,
);

class StructWithNullableStruct extends $fidl.Struct {
  const StructWithNullableStruct({
    this.val,
  });
  StructWithNullableStruct.clone(
    StructWithNullableStruct $orig, {
    Int32Wrapper? val,
  }) : this(
          val: val ?? $orig.val,
        );

  StructWithNullableStruct.cloneWithout(
    StructWithNullableStruct $orig, {
    bool val = false,
  }) : this(
          val: val ? null : $orig.val,
        );

  final Int32Wrapper? val;

  @override
  List<Object?> get $fields {
    return <Object?>[
      val,
    ];
  }

  static const $fieldType0 =
      $fidl.PointerType<Int32Wrapper>(element: kInt32Wrapper_Type);

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, val, $offset + 0, $depth);
  }

  @override
  String toString() {
    return r'StructWithNullableStruct' r'(val: ' + val.toString() + r')';
  }

  static StructWithNullableStruct _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return StructWithNullableStruct(
        val: $fieldType0.decode($decoder, $offset + 0, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithNullableStruct>
    kStructWithNullableStruct_Type = $fidl.StructType<StructWithNullableStruct>(
  inlineSize: 8,
  structDecode: StructWithNullableStruct._structDecode,
);

class StructWithNullableUnion extends $fidl.Struct {
  const StructWithNullableUnion({
    this.val,
  });
  StructWithNullableUnion.clone(
    StructWithNullableUnion $orig, {
    SimpleUnion? val,
  }) : this(
          val: val ?? $orig.val,
        );

  StructWithNullableUnion.cloneWithout(
    StructWithNullableUnion $orig, {
    bool val = false,
  }) : this(
          val: val ? null : $orig.val,
        );

  final SimpleUnion? val;

  @override
  List<Object?> get $fields {
    return <Object?>[
      val,
    ];
  }

  static const $fieldType0 = kSimpleUnion_OptType;

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, val, $offset + 0, $depth);
  }

  @override
  String toString() {
    return r'StructWithNullableUnion' r'(val: ' + val.toString() + r')';
  }

  static StructWithNullableUnion _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return StructWithNullableUnion(
        val: $fieldType0.decode($decoder, $offset + 0, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithNullableUnion> kStructWithNullableUnion_Type =
    $fidl.StructType<StructWithNullableUnion>(
  inlineSize: 24,
  structDecode: StructWithNullableUnion._structDecode,
);

// ignore: unused_element, avoid_private_typedef_functions
typedef _VoidCallback = void Function();

// add: (int a, int b) -> (int sum)
const int _kSimpleProtocol_Add_Ordinal = 0x113010d7832f175d;
const $fidl.MethodType _kSimpleProtocol_Add_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offset: 0),
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offset: 4),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offset: 0),
  ],
  name: r"SimpleProtocol.Add",
  requestInlineSize: 8,
  responseInlineSize: 8,
);

abstract class SimpleProtocol {
  $fidl.ServiceData? get $serviceData => SimpleProtocolData();
  $async.Future<int> add(int a, int b);
}

// TODO: Remove ServiceData for non-service
class SimpleProtocolData implements $fidl.ServiceData<SimpleProtocol> {
  const SimpleProtocolData();

  @override
  String getName() {
    return "";
  }

  @override
  $fidl.AsyncBinding getBinding() {
    return SimpleProtocolBinding();
  }
}

class SimpleProtocolProxy extends $fidl.AsyncProxy<SimpleProtocol>
    implements SimpleProtocol {
  SimpleProtocolProxy()
      : super($fidl.AsyncProxyController<SimpleProtocol>(
            $interfaceName: r'SimpleProtocol')) {
    ctrl.onResponse = _handleResponse;
  }
  @override
  Null get $serviceData => null;

  void _handleEvent($fidl.IncomingMessage $message) {
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.IncomingMessage $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final $async.Completer? $completer = ctrl.getCompleter($txid);
    if ($completer == null) {
      $message.closeHandles();
      return;
    }
    switch ($message.ordinal) {
      case _kSimpleProtocol_Add_Ordinal:
        final String _name = _kSimpleProtocol_Add_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kSimpleProtocol_Add_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage($message,
              _kSimpleProtocol_Add_Type.decodeResponseInlineSize(), $types[0]);

          $completer.complete($response);
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  @override
  $async.Future<int> add(int a, int b) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kSimpleProtocol_Add_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kSimpleProtocol_Add_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kSimpleProtocol_Add_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, a, $fidl.kMessageHeaderSize, 1);
      $types[1].encode($encoder, b, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

class SimpleProtocolBinding extends $fidl.AsyncBinding<SimpleProtocol> {
  SimpleProtocolBinding() : super(r"SimpleProtocol");

  @override
  void handleMessage(
      $fidl.IncomingMessage $message, $fidl.OutgoingMessageSink $respond) {
    switch ($message.ordinal) {
      case _kSimpleProtocol_Add_Ordinal:
        final String _name = _kSimpleProtocol_Add_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kSimpleProtocol_Add_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<int> $future = $fidl
              .decodeMessageWithCallback<$async.Future<int>>(
                  $message, _kSimpleProtocol_Add_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.add(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
              $types[1].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kSimpleProtocol_Add_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kSimpleProtocol_Add_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kSimpleProtocol_Add_Type.encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(
            r'Unexpected message name for SimpleProtocolBinding');
    }
  }
}
