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

library fidl_fidl_test_table_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;

// 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

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

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

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

  @override
  dynamic $field(int index) {
    switch (index) {
    }
    return null;
  }

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

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.TableType<EmptyTable> kEmptyTable_Type =
    $fidl.TableType<EmptyTable>(
  inlineSize: 16,
  members: [],
  ctor: EmptyTable._ctor,
);

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

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

  @override
  final Map<int, $fidl.UnknownRawData> $unknownData;
  final int x;
  final int y;

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

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

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.TableType<SimpleTable> kSimpleTable_Type =
    $fidl.TableType<SimpleTable>(
  inlineSize: 16,
  members: [
    $fidl.Int64Type(),
    null,
    null,
    null,
    $fidl.Int64Type(),
  ],
  ctor: SimpleTable._ctor,
);

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

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

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

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

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

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.TableType<OlderSimpleTable> kOlderSimpleTable_Type =
    $fidl.TableType<OlderSimpleTable>(
  inlineSize: 16,
  members: [
    $fidl.Int64Type(),
  ],
  ctor: OlderSimpleTable._ctor,
);

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

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

  @override
  final Map<int, $fidl.UnknownRawData> $unknownData;
  final int x;
  final int y;
  final int z;

  @override
  dynamic $field(int index) {
    switch (index) {
      case 0:
        return x;
      case 4:
        return y;
      case 5:
        return z;
    }
    return null;
  }

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

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.TableType<NewerSimpleTable> kNewerSimpleTable_Type =
    $fidl.TableType<NewerSimpleTable>(
  inlineSize: 16,
  members: [
    $fidl.Int64Type(),
    null,
    null,
    null,
    $fidl.Int64Type(),
    $fidl.Int64Type(),
  ],
  ctor: NewerSimpleTable._ctor,
);

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

  ReverseOrdinalTable._(Map<int, dynamic> argv, this.$unknownData)
      : z = argv[1],
        y = argv[2],
        x = argv[3];

  @override
  final Map<int, $fidl.UnknownRawData> $unknownData;
  final int z;
  final int y;
  final int x;

  @override
  dynamic $field(int index) {
    switch (index) {
      case 0:
        return z;
      case 1:
        return y;
      case 2:
        return x;
    }
    return null;
  }

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

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.TableType<ReverseOrdinalTable> kReverseOrdinalTable_Type =
    $fidl.TableType<ReverseOrdinalTable>(
  inlineSize: 16,
  members: [
    $fidl.Int64Type(),
    $fidl.Int64Type(),
    $fidl.Int64Type(),
  ],
  ctor: ReverseOrdinalTable._ctor,
);

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