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

