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

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

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

  @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.XUnionType<SimpleUnion> kSimpleUnion_Type =
    $fidl.XUnionType<SimpleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.Float32Type(),
  },
  ctor: SimpleUnion._ctor,
  nullable: false,
  flexible: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<SimpleUnion> kSimpleUnion_OptType =
    $fidl.XUnionType<SimpleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.Float32Type(),
  },
  ctor: SimpleUnion._ctor,
  nullable: true,
  flexible: 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,
  }) : this(
          val: val ? null : $orig.val,
        );

  final String val;

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

  static const $fieldType0 =
      $fidl.StringType(maybeElementCount: null, nullable: true);

  @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,
  }) : this(
          val: val ? null : $orig.val,
        );

  final Int32List val;

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

  static const $fieldType0 = $fidl.VectorType<Int32List>(
      element: $fidl.Int32Type(), maybeElementCount: null, nullable: true);

  @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,
  }) : this(
          val: val ? null : $orig.val,
        );

  final $zircon.Vmo val;

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

  static const $fieldType0 = $fidl.VmoType(nullable: true);

  @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,
  }) : this(
          val: val ? null : $orig.val,
        );

  final $fidl.InterfaceHandle<SimpleProtocol> val;

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

  static const $fieldType0 =
      $fidl.InterfaceHandleType<SimpleProtocol>(nullable: true);

  @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,
  }) : this(
          val: val ? null : $orig.val,
        );

  final $fidl.InterfaceRequest<SimpleProtocol> val;

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

  static const $fieldType0 =
      $fidl.InterfaceRequestType<SimpleProtocol>(nullable: true);

  @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,
  }) : 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,
  }) : 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 extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => SimpleProtocolData();
  $async.Future<int> add(int a, int b);
}

class SimpleProtocolData implements $fidl.ServiceData<SimpleProtocol> {
  const SimpleProtocolData();

  @override
  String getName() {
    return SimpleProtocol.$serviceName;
  }

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

class SimpleProtocolProxy extends $fidl.AsyncProxy<SimpleProtocol>
    implements SimpleProtocol {
  SimpleProtocolProxy()
      : super($fidl.AsyncProxyController<SimpleProtocol>(
            $serviceName: null, $interfaceName: r'SimpleProtocol')) {
    ctrl.onResponse = _handleResponse;
  }

  @override
  $fidl.ServiceData get $serviceData => SimpleProtocolData();

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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;
    }
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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;
          $decoder.claimMemory(
              _kSimpleProtocol_Add_Type.decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          $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);
    $encoder
        .alloc(_kSimpleProtocol_Add_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types = _kSimpleProtocol_Add_Type.request;
    $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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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;
          $decoder.claimMemory(
              _kSimpleProtocol_Add_Type.decodeRequestInlineSize($decoder));
          final $async.Future<int> $future = 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);
            $encoder.alloc(
                _kSimpleProtocol_Add_Type.encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kSimpleProtocol_Add_Type.response;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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');
    }
  }
}
