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

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_async.dart' as $strongly_connect_async;

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

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