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

library fidl_example_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() {
    if ($value == null) {
      return null;
    }
    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;
  }

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

  @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.XUnionType<ExampleUnion> kExampleUnion_Type =
    $fidl.XUnionType<ExampleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: ExampleUnion._ctor,
  nullable: false,
  flexible: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<ExampleUnion> kExampleUnion_OptType =
    $fidl.XUnionType<ExampleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: ExampleUnion._ctor,
  nullable: true,
  flexible: 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 {
    final ExampleXUnionTag $rawtag = _ExampleXUnionTag_map[_ordinal];
    return $rawtag == null ? ExampleXUnionTag.$unknown : $rawtag;
  }

  int get variant {
    if (_ordinal != 1) {
      return null;
    }
    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.XUnionType<ExampleXUnion> kExampleXUnion_Type =
    $fidl.XUnionType<ExampleXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: ExampleXUnion._ctor,
  nullable: false,
  flexible: true,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<ExampleXUnion> kExampleXUnion_OptType =
    $fidl.XUnionType<ExampleXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: ExampleXUnion._ctor,
  nullable: true,
  flexible: true,
);

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,
);

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

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

abstract class ExampleProtocol extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => ExampleProtocolData();
  $async.Future<void> method(lib$exampleusing.Empty arg);
}

class ExampleProtocolData implements $fidl.ServiceData<ExampleProtocol> {
  const ExampleProtocolData();

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

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

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

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

  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) {
      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);
    $encoder.alloc(
        _kExampleProtocol_Method_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types = _kExampleProtocol_Method_Type.request;
    $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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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;
          $decoder.claimMemory(
              _kExampleProtocol_Method_Type.decodeRequestInlineSize($decoder));
          final $async.Future<void> $future = 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');
    }
  }
}
