// 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) {
    $fieldType0.encode($encoder, val, $offset + 0);
  }

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

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

// 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) {
    $fieldType0.encode($encoder, val, $offset + 0);
  }

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

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

// 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.NullableVmoType();

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

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

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

// 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) {
    $fieldType0.encode($encoder, val, $offset + 0);
  }

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

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

// 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) {
    $fieldType0.encode($encoder, val, $offset + 0);
  }

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

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

// 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) {
    $fieldType0.encode($encoder, val, $offset + 0);
  }

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

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

// 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) {
    $fieldType0.encode($encoder, val, $offset + 0);
  }

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

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

// 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) {
    $fieldType0.encode($encoder, val, $offset + 0);
  }

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

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

// 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.Message $message) {
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.Message $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);
      $types[1].encode($encoder, b, $fidl.kMessageHeaderSize);
    });
    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.Message $message, $fidl.MessageSink $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),
              $types[1].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
          $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');
    }
  }
}
