// WARNING: This file is machine generated by fidlgen.

library fidl_test_name_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 $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

class EmptyTable extends $fidl.Table {
  const EmptyTable();

  EmptyTable._(Map<int, dynamic> argv);

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

  static EmptyTable _ctor(Map<int, dynamic> argv) => EmptyTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<EmptyTable> kEmptyTable_Type =
    $fidl.TableType<EmptyTable>(
  encodedSize: 16,
  members: <int, $fidl.FidlType>{},
  ctor: EmptyTable._ctor,
);

class SimpleTable extends $fidl.Table {
  const SimpleTable({
    this.x,
    this.y,
  });

  SimpleTable._(Map<int, dynamic> argv)
      : x = argv[1],
        y = argv[5];
  final int x;
  final int y;

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

  static SimpleTable _ctor(Map<int, dynamic> argv) => SimpleTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<SimpleTable> kSimpleTable_Type =
    $fidl.TableType<SimpleTable>(
  encodedSize: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    5: $fidl.Int64Type(),
  },
  ctor: SimpleTable._ctor,
);

class OlderSimpleTable extends $fidl.Table {
  const OlderSimpleTable({
    this.x,
  });

  OlderSimpleTable._(Map<int, dynamic> argv) : x = argv[1];
  final int x;

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

  static OlderSimpleTable _ctor(Map<int, dynamic> argv) =>
      OlderSimpleTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<OlderSimpleTable> kOlderSimpleTable_Type =
    $fidl.TableType<OlderSimpleTable>(
  encodedSize: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
  },
  ctor: OlderSimpleTable._ctor,
);

class NewerSimpleTable extends $fidl.Table {
  const NewerSimpleTable({
    this.x,
    this.y,
    this.z,
  });

  NewerSimpleTable._(Map<int, dynamic> argv)
      : x = argv[1],
        y = argv[5],
        z = argv[6];
  final int x;
  final int y;
  final int z;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: x,
      5: y,
      6: z,
    };
  }

  static NewerSimpleTable _ctor(Map<int, dynamic> argv) =>
      NewerSimpleTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<NewerSimpleTable> kNewerSimpleTable_Type =
    $fidl.TableType<NewerSimpleTable>(
  encodedSize: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    5: $fidl.Int64Type(),
    6: $fidl.Int64Type(),
  },
  ctor: NewerSimpleTable._ctor,
);

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