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

library fidl_fidl_test_placementofattributes_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_exampleusing/fidl_async.dart' as lib$exampleusing;
// 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

const int exampleConst = 0x0;

class ExampleEnum extends $fidl.Enum {
  factory ExampleEnum(int _v) {
    switch (_v) {
      case 0x1:
        return member;
      default:
        throw $fidl.FidlError('Invalid strict enum value: $_v',
            $fidl.FidlErrorCode.fidlInvalidEnumValue);
    }
  }
  static const ExampleEnum member = ExampleEnum._(0x1);

  const ExampleEnum._(this.$value);

  @override
  final int $value;

  static const Map<String, ExampleEnum> $valuesMap = {
    r'member': member,
  };

  static const List<ExampleEnum> $values = [
    member,
  ];

  static ExampleEnum? $valueOf(String name) => $valuesMap[name];

  @override
  bool isUnknown() {
    return false;
  }

  @override
  String toString() {
    switch ($value) {
      case 0x1:
        return r'ExampleEnum.member';
      default:
        return r'ExampleEnum.' '${$value}';
    }
  }

  static ExampleEnum _ctor(int v) => ExampleEnum(v);
}

const $fidl.EnumType<ExampleEnum> kExampleEnum_Type =
    $fidl.EnumType<ExampleEnum>(
        type: $fidl.Uint32Type(), values: {0x1: null}, ctor: ExampleEnum._ctor);

class ExampleBits extends $fidl.Bits {
  factory ExampleBits(int _v) {
    if ((_v & ~$mask.$value) != 0) {
      throw $fidl.FidlError('Bits value contains unknown bit(s): $_v',
          $fidl.FidlErrorCode.fidlInvalidBit);
    }
    return ExampleBits._(_v);
  }
  static const ExampleBits member = ExampleBits._(0x1);
  static const ExampleBits $none = ExampleBits._(0);
  static const ExampleBits $mask = ExampleBits._(0x1);

  const ExampleBits._(this.$value);

  ExampleBits operator |(ExampleBits other) {
    return ExampleBits._($value | other.$value);
  }

  ExampleBits operator &(ExampleBits other) {
    return ExampleBits._($value & other.$value);
  }

  ExampleBits operator ~() {
    return ExampleBits._(~$value & $mask.$value);
  }

  @override
  final int $value;

  @override
  bool hasUnknownBits() {
    return getUnknownBits() != 0;
  }

  @override
  int getUnknownBits() {
    return $value & ~$mask.$value;
  }

  @override
  String toString() {
    List<String> parts = [];
    if ($value & 0x1 != 0) {
      parts.add(r'ExampleBits.member');
    }
    if (parts.isEmpty) {
      return r'ExampleBits.$none';
    } else {
      return parts.join(" | ");
    }
  }

  static ExampleBits _ctor(int v) => ExampleBits(v);
}

const $fidl.BitsType<ExampleBits> kExampleBits_Type =
    $fidl.BitsType<ExampleBits>(
        type: $fidl.Uint32Type(), ctor: ExampleBits._ctor);

enum ExampleUnionTag {
  variant, // 0x1
}

const Map<int, ExampleUnionTag> _ExampleUnionTag_map = {
  1: ExampleUnionTag.variant,
};

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

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

  final int _ordinal;
  final _data;

  ExampleUnionTag get $tag => _ExampleUnionTag_map[_ordinal]!;

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

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

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'ExampleUnion.variant(' + variant.toString() + ')';
      default:
        return r'ExampleUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ExampleUnion> kExampleUnion_Type =
    $fidl.UnionType<ExampleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: ExampleUnion._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ExampleUnion> kExampleUnion_OptType =
    $fidl.NullableUnionType<ExampleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: ExampleUnion._ctor,
  flexible: false,
  resource: false,
);

enum ExampleXUnionTag {
  $unknown,
  variant, // 0x1
}

const Map<int, ExampleXUnionTag> _ExampleXUnionTag_map = {
  1: ExampleXUnionTag.variant,
};

class ExampleXUnion extends $fidl.XUnion {
  const ExampleXUnion.withVariant(int value)
      : _ordinal = 1,
        _data = value;
  const ExampleXUnion.with$UnknownData(this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  ExampleXUnionTag get $tag =>
      _ExampleXUnionTag_map[_ordinal] ?? ExampleXUnionTag.$unknown;

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

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

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'ExampleXUnion.variant(' + variant.toString() + ')';
      default:
        return r'ExampleXUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ExampleXUnion> kExampleXUnion_Type =
    $fidl.UnionType<ExampleXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: ExampleXUnion._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ExampleXUnion> kExampleXUnion_OptType =
    $fidl.NullableUnionType<ExampleXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: ExampleXUnion._ctor,
  flexible: true,
  resource: false,
);

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

  final int member;

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

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

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

  @override
  String toString() {
    return r'ExampleStruct' r'(member: ' + member.toString() + r')';
  }

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

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

class ExampleTable extends $fidl.Table {
  const ExampleTable({
    this.$unknownData,
    this.member,
  });

  ExampleTable._(Map<int, dynamic> argv, this.$unknownData) : member = argv[1];

  @override
  final Map<int, $fidl.UnknownRawData>? $unknownData;
  final int? member;

  @override
  dynamic $field(int index) {
    switch (index) {
      case 0:
        return member;
    }
    return null;
  }

  @override
  Map<int, dynamic> get $fields {
    return {
      1: member,
    };
  }

  static ExampleTable _ctor(Map<int, dynamic> argv,
          [Map<int, $fidl.UnknownRawData>? unknownData]) =>
      ExampleTable._(argv, unknownData);
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.TableType<ExampleTable> kExampleTable_Type =
    $fidl.TableType<ExampleTable>(
  inlineSize: 16,
  members: [
    $fidl.Uint32Type(),
  ],
  ctor: ExampleTable._ctor,
  resource: false,
);

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

// method: (lib$exampleusing.Empty arg)
const int _kExampleProtocol_Method_Ordinal = 0x207d2f81c0ddb184;
const $fidl.MethodType _kExampleProtocol_Method_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<lib$exampleusing.Empty>(
        type: lib$exampleusing.kEmpty_Type, offset: 0),
  ],
  response: [],
  name: r"ExampleProtocol.Method",
  requestInlineSize: 8,
  responseInlineSize: 0,
);

abstract class ExampleProtocol {
  $fidl.ServiceData? get $serviceData => ExampleProtocolData();
  $async.Future<void> method(lib$exampleusing.Empty arg);
}

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

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

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

class ExampleProtocolProxy extends $fidl.AsyncProxy<ExampleProtocol>
    implements ExampleProtocol {
  ExampleProtocolProxy()
      : super($fidl.AsyncProxyController<ExampleProtocol>(
            $interfaceName: r'ExampleProtocol')) {
    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) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  @override
  $async.Future<void> method(lib$exampleusing.Empty arg) 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(_kExampleProtocol_Method_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kExampleProtocol_Method_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kExampleProtocol_Method_Type.encodingRequestInlineSize(),
        () {
      $types[0].encode($encoder, arg, $fidl.kMessageHeaderSize);
    });
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }
}

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

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    switch ($message.ordinal) {
      case _kExampleProtocol_Method_Ordinal:
        final String _name = _kExampleProtocol_Method_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kExampleProtocol_Method_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>($message,
                  _kExampleProtocol_Method_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.method(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(
            r'Unexpected message name for ExampleProtocolBinding');
    }
  }
}
