// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// WARNING: This file is machine generated by fidlgen.

library fidl_test_name_async;

import 'dart:async';
import 'dart:developer';
import 'dart:typed_data';

import 'package:fidl/fidl.dart' as $fidl;
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart';

// These imports improve deduplication by making uses of {fidl.dart},
// {fidl_async.dart} and {fidl.dart, fidl_async.dart} generate equivalent
// packages. In AOT, the dead code will be removed by tree shaking.
// ignore: unused_import
import 'fidl.dart' as $strongly_connect_sync;

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

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) => new EmptyTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<EmptyTable> kEmptyTable_Type =
    const $fidl.TableType<EmptyTable>(
  encodedSize: 16,
  members: const <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) => new SimpleTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<SimpleTable> kSimpleTable_Type =
    const $fidl.TableType<SimpleTable>(
  encodedSize: 16,
  members: const <int, $fidl.FidlType>{
    1: const $fidl.Int64Type(),
    5: const $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) =>
      new OlderSimpleTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<OlderSimpleTable> kOlderSimpleTable_Type =
    const $fidl.TableType<OlderSimpleTable>(
  encodedSize: 16,
  members: const <int, $fidl.FidlType>{
    1: const $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) =>
      new NewerSimpleTable._(argv);
}

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

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