// automatically generated by the FlatBuffers compiler, do not modify
// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable

library my_game.example;

import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;

import './monster_test_my_game_generated.dart' as my_game;
import './monster_test_my_game.example2_generated.dart' as my_game_example2;

///  Composite components of Monster color.
class Color {
  final int value;
  const Color._(this.value);

  factory Color.fromValue(int value) {
    final result = values[value];
    if (result == null) {
      if (value == 0) {
        return Color._(0);
      } else {
        throw StateError('Invalid value $value for bit flag enum Color');
      }
    }
    return result;
  }

  static Color? _createOrNull(int? value) => 
      value == null ? null : Color.fromValue(value);

  static bool containsValue(int value) => values.containsKey(value);

  static const Color Red = Color._(1);

  ///  \brief color Green
  ///  Green is bit_flag with value (1u << 1)
  static const Color Green = Color._(2);

  ///  \brief color Blue (1u << 3)
  static const Color Blue = Color._(8);
  static const Map<int, Color> values = {
    1: Red,
    2: Green,
    8: Blue};

  static const fb.Reader<Color> reader = _ColorReader();

  @override
  String toString() {
    return 'Color{value: $value}';
  }
}

class _ColorReader extends fb.Reader<Color> {
  const _ColorReader();

  @override
  int get size => 1;

  @override
  Color read(fb.BufferContext bc, int offset) =>
      Color.fromValue(const fb.Uint8Reader().read(bc, offset));
}

class Race {
  final int value;
  const Race._(this.value);

  factory Race.fromValue(int value) {
    final result = values[value];
    if (result == null) {
        throw StateError('Invalid value $value for bit flag enum Race');
    }
    return result;
  }

  static Race? _createOrNull(int? value) => 
      value == null ? null : Race.fromValue(value);

  static const int minValue = -1;
  static const int maxValue = 2;
  static bool containsValue(int value) => values.containsKey(value);

  static const Race None = Race._(-1);
  static const Race Human = Race._(0);
  static const Race Dwarf = Race._(1);
  static const Race Elf = Race._(2);
  static const Map<int, Race> values = {
    -1: None,
    0: Human,
    1: Dwarf,
    2: Elf};

  static const fb.Reader<Race> reader = _RaceReader();

  @override
  String toString() {
    return 'Race{value: $value}';
  }
}

class _RaceReader extends fb.Reader<Race> {
  const _RaceReader();

  @override
  int get size => 1;

  @override
  Race read(fb.BufferContext bc, int offset) =>
      Race.fromValue(const fb.Int8Reader().read(bc, offset));
}

class LongEnum {
  final int value;
  const LongEnum._(this.value);

  factory LongEnum.fromValue(int value) {
    final result = values[value];
    if (result == null) {
      if (value == 0) {
        return LongEnum._(0);
      } else {
        throw StateError('Invalid value $value for bit flag enum LongEnum');
      }
    }
    return result;
  }

  static LongEnum? _createOrNull(int? value) => 
      value == null ? null : LongEnum.fromValue(value);

  static bool containsValue(int value) => values.containsKey(value);

  static const LongEnum LongOne = LongEnum._(2);
  static const LongEnum LongTwo = LongEnum._(4);
  static const LongEnum LongBig = LongEnum._(1099511627776);
  static const Map<int, LongEnum> values = {
    2: LongOne,
    4: LongTwo,
    1099511627776: LongBig};

  static const fb.Reader<LongEnum> reader = _LongEnumReader();

  @override
  String toString() {
    return 'LongEnum{value: $value}';
  }
}

class _LongEnumReader extends fb.Reader<LongEnum> {
  const _LongEnumReader();

  @override
  int get size => 8;

  @override
  LongEnum read(fb.BufferContext bc, int offset) =>
      LongEnum.fromValue(const fb.Uint64Reader().read(bc, offset));
}

class AnyTypeId {
  final int value;
  const AnyTypeId._(this.value);

  factory AnyTypeId.fromValue(int value) {
    final result = values[value];
    if (result == null) {
        throw StateError('Invalid value $value for bit flag enum AnyTypeId');
    }
    return result;
  }

  static AnyTypeId? _createOrNull(int? value) => 
      value == null ? null : AnyTypeId.fromValue(value);

  static const int minValue = 0;
  static const int maxValue = 3;
  static bool containsValue(int value) => values.containsKey(value);

  static const AnyTypeId NONE = AnyTypeId._(0);
  static const AnyTypeId Monster = AnyTypeId._(1);
  static const AnyTypeId TestSimpleTableWithEnum = AnyTypeId._(2);
  static const AnyTypeId MyGame_Example2_Monster = AnyTypeId._(3);
  static const Map<int, AnyTypeId> values = {
    0: NONE,
    1: Monster,
    2: TestSimpleTableWithEnum,
    3: MyGame_Example2_Monster};

  static const fb.Reader<AnyTypeId> reader = _AnyTypeIdReader();

  @override
  String toString() {
    return 'AnyTypeId{value: $value}';
  }
}

class _AnyTypeIdReader extends fb.Reader<AnyTypeId> {
  const _AnyTypeIdReader();

  @override
  int get size => 1;

  @override
  AnyTypeId read(fb.BufferContext bc, int offset) =>
      AnyTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
}

class AnyUniqueAliasesTypeId {
  final int value;
  const AnyUniqueAliasesTypeId._(this.value);

  factory AnyUniqueAliasesTypeId.fromValue(int value) {
    final result = values[value];
    if (result == null) {
        throw StateError('Invalid value $value for bit flag enum AnyUniqueAliasesTypeId');
    }
    return result;
  }

  static AnyUniqueAliasesTypeId? _createOrNull(int? value) => 
      value == null ? null : AnyUniqueAliasesTypeId.fromValue(value);

  static const int minValue = 0;
  static const int maxValue = 3;
  static bool containsValue(int value) => values.containsKey(value);

  static const AnyUniqueAliasesTypeId NONE = AnyUniqueAliasesTypeId._(0);
  static const AnyUniqueAliasesTypeId M = AnyUniqueAliasesTypeId._(1);
  static const AnyUniqueAliasesTypeId TS = AnyUniqueAliasesTypeId._(2);
  static const AnyUniqueAliasesTypeId M2 = AnyUniqueAliasesTypeId._(3);
  static const Map<int, AnyUniqueAliasesTypeId> values = {
    0: NONE,
    1: M,
    2: TS,
    3: M2};

  static const fb.Reader<AnyUniqueAliasesTypeId> reader = _AnyUniqueAliasesTypeIdReader();

  @override
  String toString() {
    return 'AnyUniqueAliasesTypeId{value: $value}';
  }
}

class _AnyUniqueAliasesTypeIdReader extends fb.Reader<AnyUniqueAliasesTypeId> {
  const _AnyUniqueAliasesTypeIdReader();

  @override
  int get size => 1;

  @override
  AnyUniqueAliasesTypeId read(fb.BufferContext bc, int offset) =>
      AnyUniqueAliasesTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
}

class AnyAmbiguousAliasesTypeId {
  final int value;
  const AnyAmbiguousAliasesTypeId._(this.value);

  factory AnyAmbiguousAliasesTypeId.fromValue(int value) {
    final result = values[value];
    if (result == null) {
        throw StateError('Invalid value $value for bit flag enum AnyAmbiguousAliasesTypeId');
    }
    return result;
  }

  static AnyAmbiguousAliasesTypeId? _createOrNull(int? value) => 
      value == null ? null : AnyAmbiguousAliasesTypeId.fromValue(value);

  static const int minValue = 0;
  static const int maxValue = 3;
  static bool containsValue(int value) => values.containsKey(value);

  static const AnyAmbiguousAliasesTypeId NONE = AnyAmbiguousAliasesTypeId._(0);
  static const AnyAmbiguousAliasesTypeId M1 = AnyAmbiguousAliasesTypeId._(1);
  static const AnyAmbiguousAliasesTypeId M2 = AnyAmbiguousAliasesTypeId._(2);
  static const AnyAmbiguousAliasesTypeId M3 = AnyAmbiguousAliasesTypeId._(3);
  static const Map<int, AnyAmbiguousAliasesTypeId> values = {
    0: NONE,
    1: M1,
    2: M2,
    3: M3};

  static const fb.Reader<AnyAmbiguousAliasesTypeId> reader = _AnyAmbiguousAliasesTypeIdReader();

  @override
  String toString() {
    return 'AnyAmbiguousAliasesTypeId{value: $value}';
  }
}

class _AnyAmbiguousAliasesTypeIdReader extends fb.Reader<AnyAmbiguousAliasesTypeId> {
  const _AnyAmbiguousAliasesTypeIdReader();

  @override
  int get size => 1;

  @override
  AnyAmbiguousAliasesTypeId read(fb.BufferContext bc, int offset) =>
      AnyAmbiguousAliasesTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
}

class Test {
  Test._(this._bc, this._bcOffset);

  static const fb.Reader<Test> reader = _TestReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  int get a => const fb.Int16Reader().read(_bc, _bcOffset + 0);
  int get b => const fb.Int8Reader().read(_bc, _bcOffset + 2);

  @override
  String toString() {
    return 'Test{a: ${a}, b: ${b}}';
  }

  TestT unpack() => TestT(
      a: a,
      b: b);

  static int pack(fb.Builder fbBuilder, TestT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class TestT implements fb.Packable {
  int a;
  int b;

  TestT({
      required this.a,
      required this.b});

  @override
  int pack(fb.Builder fbBuilder) {
    fbBuilder.pad(1);
    fbBuilder.putInt8(b);
    fbBuilder.putInt16(a);
    return fbBuilder.offset;
  }

  @override
  String toString() {
    return 'TestT{a: ${a}, b: ${b}}';
  }
}

class _TestReader extends fb.StructReader<Test> {
  const _TestReader();

  @override
  int get size => 4;

  @override
  Test createObject(fb.BufferContext bc, int offset) => 
    Test._(bc, offset);
}

class TestBuilder {
  TestBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  int finish(int a, int b) {
    fbBuilder.pad(1);
    fbBuilder.putInt8(b);
    fbBuilder.putInt16(a);
    return fbBuilder.offset;
  }

}

class TestObjectBuilder extends fb.ObjectBuilder {
  final int _a;
  final int _b;

  TestObjectBuilder({
    required int a,
    required int b,
  })
      : _a = a,
        _b = b;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    fbBuilder.pad(1);
    fbBuilder.putInt8(_b);
    fbBuilder.putInt16(_a);
    return fbBuilder.offset;
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
class TestSimpleTableWithEnum {
  TestSimpleTableWithEnum._(this._bc, this._bcOffset);
  factory TestSimpleTableWithEnum(List<int> bytes) {
    final rootRef = fb.BufferContext.fromBytes(bytes);
    return reader.read(rootRef, 0);
  }

  static const fb.Reader<TestSimpleTableWithEnum> reader = _TestSimpleTableWithEnumReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  Color get color => Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 4, 2));

  @override
  String toString() {
    return 'TestSimpleTableWithEnum{color: ${color}}';
  }

  TestSimpleTableWithEnumT unpack() => TestSimpleTableWithEnumT(
      color: color);

  static int pack(fb.Builder fbBuilder, TestSimpleTableWithEnumT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class TestSimpleTableWithEnumT implements fb.Packable {
  Color color;

  TestSimpleTableWithEnumT({
      this.color = Color.Green});

  @override
  int pack(fb.Builder fbBuilder) {
    fbBuilder.startTable(1);
    fbBuilder.addUint8(0, color.value);
    return fbBuilder.endTable();
  }

  @override
  String toString() {
    return 'TestSimpleTableWithEnumT{color: ${color}}';
  }
}

class _TestSimpleTableWithEnumReader extends fb.TableReader<TestSimpleTableWithEnum> {
  const _TestSimpleTableWithEnumReader();

  @override
  TestSimpleTableWithEnum createObject(fb.BufferContext bc, int offset) => 
    TestSimpleTableWithEnum._(bc, offset);
}

class TestSimpleTableWithEnumBuilder {
  TestSimpleTableWithEnumBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  void begin() {
    fbBuilder.startTable(1);
  }

  int addColor(Color? color) {
    fbBuilder.addUint8(0, color?.value);
    return fbBuilder.offset;
  }

  int finish() {
    return fbBuilder.endTable();
  }
}

class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder {
  final Color? _color;

  TestSimpleTableWithEnumObjectBuilder({
    Color? color,
  })
      : _color = color;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    fbBuilder.startTable(1);
    fbBuilder.addUint8(0, _color?.value);
    return fbBuilder.endTable();
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
class Vec3 {
  Vec3._(this._bc, this._bcOffset);

  static const fb.Reader<Vec3> reader = _Vec3Reader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  double get x => const fb.Float32Reader().read(_bc, _bcOffset + 0);
  double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
  double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
  double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
  Color get test2 => Color.fromValue(const fb.Uint8Reader().read(_bc, _bcOffset + 24));
  Test get test3 => Test.reader.read(_bc, _bcOffset + 26);

  @override
  String toString() {
    return 'Vec3{x: ${x}, y: ${y}, z: ${z}, test1: ${test1}, test2: ${test2}, test3: ${test3}}';
  }

  Vec3T unpack() => Vec3T(
      x: x,
      y: y,
      z: z,
      test1: test1,
      test2: test2,
      test3: test3.unpack());

  static int pack(fb.Builder fbBuilder, Vec3T? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class Vec3T implements fb.Packable {
  double x;
  double y;
  double z;
  double test1;
  Color test2;
  TestT test3;

  Vec3T({
      required this.x,
      required this.y,
      required this.z,
      required this.test1,
      required this.test2,
      required this.test3});

  @override
  int pack(fb.Builder fbBuilder) {
    fbBuilder.pad(2);
    test3.pack(fbBuilder);
    fbBuilder.pad(1);
    fbBuilder.putUint8(test2.value);
    fbBuilder.putFloat64(test1);
    fbBuilder.pad(4);
    fbBuilder.putFloat32(z);
    fbBuilder.putFloat32(y);
    fbBuilder.putFloat32(x);
    return fbBuilder.offset;
  }

  @override
  String toString() {
    return 'Vec3T{x: ${x}, y: ${y}, z: ${z}, test1: ${test1}, test2: ${test2}, test3: ${test3}}';
  }
}

class _Vec3Reader extends fb.StructReader<Vec3> {
  const _Vec3Reader();

  @override
  int get size => 32;

  @override
  Vec3 createObject(fb.BufferContext bc, int offset) => 
    Vec3._(bc, offset);
}

class Vec3Builder {
  Vec3Builder(this.fbBuilder);

  final fb.Builder fbBuilder;

  int finish(double x, double y, double z, double test1, Color test2, fb.StructBuilder test3) {
    fbBuilder.pad(2);
    test3();
    fbBuilder.pad(1);
    fbBuilder.putUint8(test2.value);
    fbBuilder.putFloat64(test1);
    fbBuilder.pad(4);
    fbBuilder.putFloat32(z);
    fbBuilder.putFloat32(y);
    fbBuilder.putFloat32(x);
    return fbBuilder.offset;
  }

}

class Vec3ObjectBuilder extends fb.ObjectBuilder {
  final double _x;
  final double _y;
  final double _z;
  final double _test1;
  final Color _test2;
  final TestObjectBuilder _test3;

  Vec3ObjectBuilder({
    required double x,
    required double y,
    required double z,
    required double test1,
    required Color test2,
    required TestObjectBuilder test3,
  })
      : _x = x,
        _y = y,
        _z = z,
        _test1 = test1,
        _test2 = test2,
        _test3 = test3;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    fbBuilder.pad(2);
    _test3.finish(fbBuilder);
    fbBuilder.pad(1);
    fbBuilder.putUint8(_test2.value);
    fbBuilder.putFloat64(_test1);
    fbBuilder.pad(4);
    fbBuilder.putFloat32(_z);
    fbBuilder.putFloat32(_y);
    fbBuilder.putFloat32(_x);
    return fbBuilder.offset;
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
class Ability {
  Ability._(this._bc, this._bcOffset);

  static const fb.Reader<Ability> reader = _AbilityReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  int get id => const fb.Uint32Reader().read(_bc, _bcOffset + 0);
  int get distance => const fb.Uint32Reader().read(_bc, _bcOffset + 4);

  @override
  String toString() {
    return 'Ability{id: ${id}, distance: ${distance}}';
  }

  AbilityT unpack() => AbilityT(
      id: id,
      distance: distance);

  static int pack(fb.Builder fbBuilder, AbilityT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class AbilityT implements fb.Packable {
  int id;
  int distance;

  AbilityT({
      required this.id,
      required this.distance});

  @override
  int pack(fb.Builder fbBuilder) {
    fbBuilder.putUint32(distance);
    fbBuilder.putUint32(id);
    return fbBuilder.offset;
  }

  @override
  String toString() {
    return 'AbilityT{id: ${id}, distance: ${distance}}';
  }
}

class _AbilityReader extends fb.StructReader<Ability> {
  const _AbilityReader();

  @override
  int get size => 8;

  @override
  Ability createObject(fb.BufferContext bc, int offset) => 
    Ability._(bc, offset);
}

class AbilityBuilder {
  AbilityBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  int finish(int id, int distance) {
    fbBuilder.putUint32(distance);
    fbBuilder.putUint32(id);
    return fbBuilder.offset;
  }

}

class AbilityObjectBuilder extends fb.ObjectBuilder {
  final int _id;
  final int _distance;

  AbilityObjectBuilder({
    required int id,
    required int distance,
  })
      : _id = id,
        _distance = distance;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    fbBuilder.putUint32(_distance);
    fbBuilder.putUint32(_id);
    return fbBuilder.offset;
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
class StructOfStructs {
  StructOfStructs._(this._bc, this._bcOffset);

  static const fb.Reader<StructOfStructs> reader = _StructOfStructsReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  Ability get a => Ability.reader.read(_bc, _bcOffset + 0);
  Test get b => Test.reader.read(_bc, _bcOffset + 8);
  Ability get c => Ability.reader.read(_bc, _bcOffset + 12);

  @override
  String toString() {
    return 'StructOfStructs{a: ${a}, b: ${b}, c: ${c}}';
  }

  StructOfStructsT unpack() => StructOfStructsT(
      a: a.unpack(),
      b: b.unpack(),
      c: c.unpack());

  static int pack(fb.Builder fbBuilder, StructOfStructsT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class StructOfStructsT implements fb.Packable {
  AbilityT a;
  TestT b;
  AbilityT c;

  StructOfStructsT({
      required this.a,
      required this.b,
      required this.c});

  @override
  int pack(fb.Builder fbBuilder) {
    c.pack(fbBuilder);
    b.pack(fbBuilder);
    a.pack(fbBuilder);
    return fbBuilder.offset;
  }

  @override
  String toString() {
    return 'StructOfStructsT{a: ${a}, b: ${b}, c: ${c}}';
  }
}

class _StructOfStructsReader extends fb.StructReader<StructOfStructs> {
  const _StructOfStructsReader();

  @override
  int get size => 20;

  @override
  StructOfStructs createObject(fb.BufferContext bc, int offset) => 
    StructOfStructs._(bc, offset);
}

class StructOfStructsBuilder {
  StructOfStructsBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  int finish(fb.StructBuilder a, fb.StructBuilder b, fb.StructBuilder c) {
    c();
    b();
    a();
    return fbBuilder.offset;
  }

}

class StructOfStructsObjectBuilder extends fb.ObjectBuilder {
  final AbilityObjectBuilder _a;
  final TestObjectBuilder _b;
  final AbilityObjectBuilder _c;

  StructOfStructsObjectBuilder({
    required AbilityObjectBuilder a,
    required TestObjectBuilder b,
    required AbilityObjectBuilder c,
  })
      : _a = a,
        _b = b,
        _c = c;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    _c.finish(fbBuilder);
    _b.finish(fbBuilder);
    _a.finish(fbBuilder);
    return fbBuilder.offset;
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
class StructOfStructsOfStructs {
  StructOfStructsOfStructs._(this._bc, this._bcOffset);

  static const fb.Reader<StructOfStructsOfStructs> reader = _StructOfStructsOfStructsReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  StructOfStructs get a => StructOfStructs.reader.read(_bc, _bcOffset + 0);

  @override
  String toString() {
    return 'StructOfStructsOfStructs{a: ${a}}';
  }

  StructOfStructsOfStructsT unpack() => StructOfStructsOfStructsT(
      a: a.unpack());

  static int pack(fb.Builder fbBuilder, StructOfStructsOfStructsT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class StructOfStructsOfStructsT implements fb.Packable {
  StructOfStructsT a;

  StructOfStructsOfStructsT({
      required this.a});

  @override
  int pack(fb.Builder fbBuilder) {
    a.pack(fbBuilder);
    return fbBuilder.offset;
  }

  @override
  String toString() {
    return 'StructOfStructsOfStructsT{a: ${a}}';
  }
}

class _StructOfStructsOfStructsReader extends fb.StructReader<StructOfStructsOfStructs> {
  const _StructOfStructsOfStructsReader();

  @override
  int get size => 20;

  @override
  StructOfStructsOfStructs createObject(fb.BufferContext bc, int offset) => 
    StructOfStructsOfStructs._(bc, offset);
}

class StructOfStructsOfStructsBuilder {
  StructOfStructsOfStructsBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  int finish(fb.StructBuilder a) {
    a();
    return fbBuilder.offset;
  }

}

class StructOfStructsOfStructsObjectBuilder extends fb.ObjectBuilder {
  final StructOfStructsObjectBuilder _a;

  StructOfStructsOfStructsObjectBuilder({
    required StructOfStructsObjectBuilder a,
  })
      : _a = a;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    _a.finish(fbBuilder);
    return fbBuilder.offset;
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
class Stat {
  Stat._(this._bc, this._bcOffset);
  factory Stat(List<int> bytes) {
    final rootRef = fb.BufferContext.fromBytes(bytes);
    return reader.read(rootRef, 0);
  }

  static const fb.Reader<Stat> reader = _StatReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  String? get id => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 4);
  int get val => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 6, 0);
  int get count => const fb.Uint16Reader().vTableGet(_bc, _bcOffset, 8, 0);

  @override
  String toString() {
    return 'Stat{id: ${id}, val: ${val}, count: ${count}}';
  }

  StatT unpack() => StatT(
      id: id,
      val: val,
      count: count);

  static int pack(fb.Builder fbBuilder, StatT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class StatT implements fb.Packable {
  String? id;
  int val;
  int count;

  StatT({
      this.id,
      this.val = 0,
      this.count = 0});

  @override
  int pack(fb.Builder fbBuilder) {
    final int? idOffset = id == null ? null
        : fbBuilder.writeString(id!);
    fbBuilder.startTable(3);
    fbBuilder.addOffset(0, idOffset);
    fbBuilder.addInt64(1, val);
    fbBuilder.addUint16(2, count);
    return fbBuilder.endTable();
  }

  @override
  String toString() {
    return 'StatT{id: ${id}, val: ${val}, count: ${count}}';
  }
}

class _StatReader extends fb.TableReader<Stat> {
  const _StatReader();

  @override
  Stat createObject(fb.BufferContext bc, int offset) => 
    Stat._(bc, offset);
}

class StatBuilder {
  StatBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  void begin() {
    fbBuilder.startTable(3);
  }

  int addIdOffset(int? offset) {
    fbBuilder.addOffset(0, offset);
    return fbBuilder.offset;
  }
  int addVal(int? val) {
    fbBuilder.addInt64(1, val);
    return fbBuilder.offset;
  }
  int addCount(int? count) {
    fbBuilder.addUint16(2, count);
    return fbBuilder.offset;
  }

  int finish() {
    return fbBuilder.endTable();
  }
}

class StatObjectBuilder extends fb.ObjectBuilder {
  final String? _id;
  final int? _val;
  final int? _count;

  StatObjectBuilder({
    String? id,
    int? val,
    int? count,
  })
      : _id = id,
        _val = val,
        _count = count;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    final int? idOffset = _id == null ? null
        : fbBuilder.writeString(_id!);
    fbBuilder.startTable(3);
    fbBuilder.addOffset(0, idOffset);
    fbBuilder.addInt64(1, _val);
    fbBuilder.addUint16(2, _count);
    return fbBuilder.endTable();
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
class Referrable {
  Referrable._(this._bc, this._bcOffset);
  factory Referrable(List<int> bytes) {
    final rootRef = fb.BufferContext.fromBytes(bytes);
    return reader.read(rootRef, 0);
  }

  static const fb.Reader<Referrable> reader = _ReferrableReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  int get id => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 4, 0);

  @override
  String toString() {
    return 'Referrable{id: ${id}}';
  }

  ReferrableT unpack() => ReferrableT(
      id: id);

  static int pack(fb.Builder fbBuilder, ReferrableT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class ReferrableT implements fb.Packable {
  int id;

  ReferrableT({
      this.id = 0});

  @override
  int pack(fb.Builder fbBuilder) {
    fbBuilder.startTable(1);
    fbBuilder.addUint64(0, id);
    return fbBuilder.endTable();
  }

  @override
  String toString() {
    return 'ReferrableT{id: ${id}}';
  }
}

class _ReferrableReader extends fb.TableReader<Referrable> {
  const _ReferrableReader();

  @override
  Referrable createObject(fb.BufferContext bc, int offset) => 
    Referrable._(bc, offset);
}

class ReferrableBuilder {
  ReferrableBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  void begin() {
    fbBuilder.startTable(1);
  }

  int addId(int? id) {
    fbBuilder.addUint64(0, id);
    return fbBuilder.offset;
  }

  int finish() {
    return fbBuilder.endTable();
  }
}

class ReferrableObjectBuilder extends fb.ObjectBuilder {
  final int? _id;

  ReferrableObjectBuilder({
    int? id,
  })
      : _id = id;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    fbBuilder.startTable(1);
    fbBuilder.addUint64(0, _id);
    return fbBuilder.endTable();
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
///  an example documentation comment: "monster object"
class Monster {
  Monster._(this._bc, this._bcOffset);
  factory Monster(List<int> bytes) {
    final rootRef = fb.BufferContext.fromBytes(bytes);
    return reader.read(rootRef, 0);
  }

  static const fb.Reader<Monster> reader = _MonsterReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  Vec3? get pos => Vec3.reader.vTableGetNullable(_bc, _bcOffset, 4);
  int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
  int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
  String? get name => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 10);
  List<int>? get inventory => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 14);
  Color get color => Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 16, 8));
  AnyTypeId? get testType => AnyTypeId._createOrNull(const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 18));
  dynamic get test {
    switch (testType?.value) {
      case 1: return Monster.reader.vTableGetNullable(_bc, _bcOffset, 20);
      case 2: return TestSimpleTableWithEnum.reader.vTableGetNullable(_bc, _bcOffset, 20);
      case 3: return my_game_example2.Monster.reader.vTableGetNullable(_bc, _bcOffset, 20);
      default: return null;
    }
  }
  List<Test>? get test4 => const fb.ListReader<Test>(Test.reader).vTableGetNullable(_bc, _bcOffset, 22);
  List<String>? get testarrayofstring => const fb.ListReader<String>(fb.StringReader()).vTableGetNullable(_bc, _bcOffset, 24);
  ///  an example documentation comment: this will end up in the generated code
  ///  multiline too
  List<Monster>? get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGetNullable(_bc, _bcOffset, 26);
  Monster? get enemy => Monster.reader.vTableGetNullable(_bc, _bcOffset, 28);
  List<int>? get testnestedflatbuffer => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 30);
  Stat? get testempty => Stat.reader.vTableGetNullable(_bc, _bcOffset, 32);
  bool get testbool => const fb.BoolReader().vTableGet(_bc, _bcOffset, 34, false);
  int get testhashs32Fnv1 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 36, 0);
  int get testhashu32Fnv1 => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 38, 0);
  int get testhashs64Fnv1 => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 40, 0);
  int get testhashu64Fnv1 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 42, 0);
  int get testhashs32Fnv1a => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 44, 0);
  int get testhashu32Fnv1a => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 46, 0);
  int get testhashs64Fnv1a => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 48, 0);
  int get testhashu64Fnv1a => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 50, 0);
  List<bool>? get testarrayofbools => const fb.ListReader<bool>(fb.BoolReader()).vTableGetNullable(_bc, _bcOffset, 52);
  double get testf => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 54, 3.14159);
  double get testf2 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 56, 3.0);
  double get testf3 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 58, 0.0);
  List<String>? get testarrayofstring2 => const fb.ListReader<String>(fb.StringReader()).vTableGetNullable(_bc, _bcOffset, 60);
  List<Ability>? get testarrayofsortedstruct => const fb.ListReader<Ability>(Ability.reader).vTableGetNullable(_bc, _bcOffset, 62);
  List<int>? get flex => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 64);
  List<Test>? get test5 => const fb.ListReader<Test>(Test.reader).vTableGetNullable(_bc, _bcOffset, 66);
  List<int>? get vectorOfLongs => const fb.ListReader<int>(fb.Int64Reader()).vTableGetNullable(_bc, _bcOffset, 68);
  List<double>? get vectorOfDoubles => const fb.ListReader<double>(fb.Float64Reader()).vTableGetNullable(_bc, _bcOffset, 70);
  my_game.InParentNamespace? get parentNamespaceTest => my_game.InParentNamespace.reader.vTableGetNullable(_bc, _bcOffset, 72);
  List<Referrable>? get vectorOfReferrables => const fb.ListReader<Referrable>(Referrable.reader).vTableGetNullable(_bc, _bcOffset, 74);
  int get singleWeakReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 76, 0);
  List<int>? get vectorOfWeakReferences => const fb.ListReader<int>(fb.Uint64Reader()).vTableGetNullable(_bc, _bcOffset, 78);
  List<Referrable>? get vectorOfStrongReferrables => const fb.ListReader<Referrable>(Referrable.reader).vTableGetNullable(_bc, _bcOffset, 80);
  int get coOwningReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 82, 0);
  List<int>? get vectorOfCoOwningReferences => const fb.ListReader<int>(fb.Uint64Reader()).vTableGetNullable(_bc, _bcOffset, 84);
  int get nonOwningReference => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 86, 0);
  List<int>? get vectorOfNonOwningReferences => const fb.ListReader<int>(fb.Uint64Reader()).vTableGetNullable(_bc, _bcOffset, 88);
  AnyUniqueAliasesTypeId? get anyUniqueType => AnyUniqueAliasesTypeId._createOrNull(const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 90));
  dynamic get anyUnique {
    switch (anyUniqueType?.value) {
      case 1: return Monster.reader.vTableGetNullable(_bc, _bcOffset, 92);
      case 2: return TestSimpleTableWithEnum.reader.vTableGetNullable(_bc, _bcOffset, 92);
      case 3: return my_game_example2.Monster.reader.vTableGetNullable(_bc, _bcOffset, 92);
      default: return null;
    }
  }
  AnyAmbiguousAliasesTypeId? get anyAmbiguousType => AnyAmbiguousAliasesTypeId._createOrNull(const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 94));
  dynamic get anyAmbiguous {
    switch (anyAmbiguousType?.value) {
      case 1: return Monster.reader.vTableGetNullable(_bc, _bcOffset, 96);
      case 2: return Monster.reader.vTableGetNullable(_bc, _bcOffset, 96);
      case 3: return Monster.reader.vTableGetNullable(_bc, _bcOffset, 96);
      default: return null;
    }
  }
  List<Color>? get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGetNullable(_bc, _bcOffset, 98);
  Race get signedEnum => Race.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 100, -1));
  List<int>? get testrequirednestedflatbuffer => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 102);
  List<Stat>? get scalarKeySortedTables => const fb.ListReader<Stat>(Stat.reader).vTableGetNullable(_bc, _bcOffset, 104);
  Test? get nativeInline => Test.reader.vTableGetNullable(_bc, _bcOffset, 106);
  LongEnum get longEnumNonEnumDefault => LongEnum.fromValue(const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 108, 0));
  LongEnum get longEnumNormalDefault => LongEnum.fromValue(const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 110, 2));

  @override
  String toString() {
    return 'Monster{pos: ${pos}, mana: ${mana}, hp: ${hp}, name: ${name}, inventory: ${inventory}, color: ${color}, testType: ${testType}, test: ${test}, test4: ${test4}, testarrayofstring: ${testarrayofstring}, testarrayoftables: ${testarrayoftables}, enemy: ${enemy}, testnestedflatbuffer: ${testnestedflatbuffer}, testempty: ${testempty}, testbool: ${testbool}, testhashs32Fnv1: ${testhashs32Fnv1}, testhashu32Fnv1: ${testhashu32Fnv1}, testhashs64Fnv1: ${testhashs64Fnv1}, testhashu64Fnv1: ${testhashu64Fnv1}, testhashs32Fnv1a: ${testhashs32Fnv1a}, testhashu32Fnv1a: ${testhashu32Fnv1a}, testhashs64Fnv1a: ${testhashs64Fnv1a}, testhashu64Fnv1a: ${testhashu64Fnv1a}, testarrayofbools: ${testarrayofbools}, testf: ${testf}, testf2: ${testf2}, testf3: ${testf3}, testarrayofstring2: ${testarrayofstring2}, testarrayofsortedstruct: ${testarrayofsortedstruct}, flex: ${flex}, test5: ${test5}, vectorOfLongs: ${vectorOfLongs}, vectorOfDoubles: ${vectorOfDoubles}, parentNamespaceTest: ${parentNamespaceTest}, vectorOfReferrables: ${vectorOfReferrables}, singleWeakReference: ${singleWeakReference}, vectorOfWeakReferences: ${vectorOfWeakReferences}, vectorOfStrongReferrables: ${vectorOfStrongReferrables}, coOwningReference: ${coOwningReference}, vectorOfCoOwningReferences: ${vectorOfCoOwningReferences}, nonOwningReference: ${nonOwningReference}, vectorOfNonOwningReferences: ${vectorOfNonOwningReferences}, anyUniqueType: ${anyUniqueType}, anyUnique: ${anyUnique}, anyAmbiguousType: ${anyAmbiguousType}, anyAmbiguous: ${anyAmbiguous}, vectorOfEnums: ${vectorOfEnums}, signedEnum: ${signedEnum}, testrequirednestedflatbuffer: ${testrequirednestedflatbuffer}, scalarKeySortedTables: ${scalarKeySortedTables}, nativeInline: ${nativeInline}, longEnumNonEnumDefault: ${longEnumNonEnumDefault}, longEnumNormalDefault: ${longEnumNormalDefault}}';
  }

  MonsterT unpack() => MonsterT(
      pos: pos?.unpack(),
      mana: mana,
      hp: hp,
      name: name,
      inventory: const fb.Uint8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 14),
      color: color,
      testType: testType,
      test: test,
      test4: test4?.map((e) => e.unpack()).toList(),
      testarrayofstring: const fb.ListReader<String>(fb.StringReader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 24),
      testarrayoftables: testarrayoftables?.map((e) => e.unpack()).toList(),
      enemy: enemy?.unpack(),
      testnestedflatbuffer: const fb.Uint8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 30),
      testempty: testempty?.unpack(),
      testbool: testbool,
      testhashs32Fnv1: testhashs32Fnv1,
      testhashu32Fnv1: testhashu32Fnv1,
      testhashs64Fnv1: testhashs64Fnv1,
      testhashu64Fnv1: testhashu64Fnv1,
      testhashs32Fnv1a: testhashs32Fnv1a,
      testhashu32Fnv1a: testhashu32Fnv1a,
      testhashs64Fnv1a: testhashs64Fnv1a,
      testhashu64Fnv1a: testhashu64Fnv1a,
      testarrayofbools: const fb.ListReader<bool>(fb.BoolReader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 52),
      testf: testf,
      testf2: testf2,
      testf3: testf3,
      testarrayofstring2: const fb.ListReader<String>(fb.StringReader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 60),
      testarrayofsortedstruct: testarrayofsortedstruct?.map((e) => e.unpack()).toList(),
      flex: const fb.Uint8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 64),
      test5: test5?.map((e) => e.unpack()).toList(),
      vectorOfLongs: const fb.ListReader<int>(fb.Int64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 68),
      vectorOfDoubles: const fb.ListReader<double>(fb.Float64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 70),
      parentNamespaceTest: parentNamespaceTest?.unpack(),
      vectorOfReferrables: vectorOfReferrables?.map((e) => e.unpack()).toList(),
      singleWeakReference: singleWeakReference,
      vectorOfWeakReferences: const fb.ListReader<int>(fb.Uint64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 78),
      vectorOfStrongReferrables: vectorOfStrongReferrables?.map((e) => e.unpack()).toList(),
      coOwningReference: coOwningReference,
      vectorOfCoOwningReferences: const fb.ListReader<int>(fb.Uint64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 84),
      nonOwningReference: nonOwningReference,
      vectorOfNonOwningReferences: const fb.ListReader<int>(fb.Uint64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 88),
      anyUniqueType: anyUniqueType,
      anyUnique: anyUnique,
      anyAmbiguousType: anyAmbiguousType,
      anyAmbiguous: anyAmbiguous,
      vectorOfEnums: const fb.ListReader<Color>(Color.reader, lazy: false).vTableGetNullable(_bc, _bcOffset, 98),
      signedEnum: signedEnum,
      testrequirednestedflatbuffer: const fb.Uint8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 102),
      scalarKeySortedTables: scalarKeySortedTables?.map((e) => e.unpack()).toList(),
      nativeInline: nativeInline?.unpack(),
      longEnumNonEnumDefault: longEnumNonEnumDefault,
      longEnumNormalDefault: longEnumNormalDefault);

  static int pack(fb.Builder fbBuilder, MonsterT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

///  an example documentation comment: "monster object"
class MonsterT implements fb.Packable {
  Vec3T? pos;
  int mana;
  int hp;
  String? name;
  List<int>? inventory;
  Color color;
  AnyTypeId? testType;
  dynamic test;
  List<TestT>? test4;
  List<String>? testarrayofstring;
  ///  an example documentation comment: this will end up in the generated code
  ///  multiline too
  List<MonsterT>? testarrayoftables;
  MonsterT? enemy;
  List<int>? testnestedflatbuffer;
  StatT? testempty;
  bool testbool;
  int testhashs32Fnv1;
  int testhashu32Fnv1;
  int testhashs64Fnv1;
  int testhashu64Fnv1;
  int testhashs32Fnv1a;
  int testhashu32Fnv1a;
  int testhashs64Fnv1a;
  int testhashu64Fnv1a;
  List<bool>? testarrayofbools;
  double testf;
  double testf2;
  double testf3;
  List<String>? testarrayofstring2;
  List<AbilityT>? testarrayofsortedstruct;
  List<int>? flex;
  List<TestT>? test5;
  List<int>? vectorOfLongs;
  List<double>? vectorOfDoubles;
  my_game.InParentNamespaceT? parentNamespaceTest;
  List<ReferrableT>? vectorOfReferrables;
  int singleWeakReference;
  List<int>? vectorOfWeakReferences;
  List<ReferrableT>? vectorOfStrongReferrables;
  int coOwningReference;
  List<int>? vectorOfCoOwningReferences;
  int nonOwningReference;
  List<int>? vectorOfNonOwningReferences;
  AnyUniqueAliasesTypeId? anyUniqueType;
  dynamic anyUnique;
  AnyAmbiguousAliasesTypeId? anyAmbiguousType;
  dynamic anyAmbiguous;
  List<Color>? vectorOfEnums;
  Race signedEnum;
  List<int>? testrequirednestedflatbuffer;
  List<StatT>? scalarKeySortedTables;
  TestT? nativeInline;
  LongEnum longEnumNonEnumDefault;
  LongEnum longEnumNormalDefault;

  MonsterT({
      this.pos,
      this.mana = 150,
      this.hp = 100,
      this.name,
      this.inventory,
      this.color = Color.Blue,
      this.testType,
      this.test,
      this.test4,
      this.testarrayofstring,
      this.testarrayoftables,
      this.enemy,
      this.testnestedflatbuffer,
      this.testempty,
      this.testbool = false,
      this.testhashs32Fnv1 = 0,
      this.testhashu32Fnv1 = 0,
      this.testhashs64Fnv1 = 0,
      this.testhashu64Fnv1 = 0,
      this.testhashs32Fnv1a = 0,
      this.testhashu32Fnv1a = 0,
      this.testhashs64Fnv1a = 0,
      this.testhashu64Fnv1a = 0,
      this.testarrayofbools,
      this.testf = 3.14159,
      this.testf2 = 3.0,
      this.testf3 = 0.0,
      this.testarrayofstring2,
      this.testarrayofsortedstruct,
      this.flex,
      this.test5,
      this.vectorOfLongs,
      this.vectorOfDoubles,
      this.parentNamespaceTest,
      this.vectorOfReferrables,
      this.singleWeakReference = 0,
      this.vectorOfWeakReferences,
      this.vectorOfStrongReferrables,
      this.coOwningReference = 0,
      this.vectorOfCoOwningReferences,
      this.nonOwningReference = 0,
      this.vectorOfNonOwningReferences,
      this.anyUniqueType,
      this.anyUnique,
      this.anyAmbiguousType,
      this.anyAmbiguous,
      this.vectorOfEnums,
      this.signedEnum = Race.None,
      this.testrequirednestedflatbuffer,
      this.scalarKeySortedTables,
      this.nativeInline,
      this.longEnumNonEnumDefault = const LongEnum._(0),
      this.longEnumNormalDefault = LongEnum.LongOne});

  @override
  int pack(fb.Builder fbBuilder) {
    final int? nameOffset = name == null ? null
        : fbBuilder.writeString(name!);
    final int? inventoryOffset = inventory == null ? null
        : fbBuilder.writeListUint8(inventory!);
    final int? testOffset = test?.pack(fbBuilder);
    int? test4Offset;
    if (test4 != null) {
      for (var e in test4!) { e.pack(fbBuilder); }
      test4Offset = fbBuilder.endStructVector(test4!.length);
    }
    final int? testarrayofstringOffset = testarrayofstring == null ? null
        : fbBuilder.writeList(testarrayofstring!.map(fbBuilder.writeString).toList());
    final int? testarrayoftablesOffset = testarrayoftables == null ? null
        : fbBuilder.writeList(testarrayoftables!.map((b) => b.pack(fbBuilder)).toList());
    final int? enemyOffset = enemy?.pack(fbBuilder);
    final int? testnestedflatbufferOffset = testnestedflatbuffer == null ? null
        : fbBuilder.writeListUint8(testnestedflatbuffer!);
    final int? testemptyOffset = testempty?.pack(fbBuilder);
    final int? testarrayofboolsOffset = testarrayofbools == null ? null
        : fbBuilder.writeListBool(testarrayofbools!);
    final int? testarrayofstring2Offset = testarrayofstring2 == null ? null
        : fbBuilder.writeList(testarrayofstring2!.map(fbBuilder.writeString).toList());
    int? testarrayofsortedstructOffset;
    if (testarrayofsortedstruct != null) {
      for (var e in testarrayofsortedstruct!) { e.pack(fbBuilder); }
      testarrayofsortedstructOffset = fbBuilder.endStructVector(testarrayofsortedstruct!.length);
    }
    final int? flexOffset = flex == null ? null
        : fbBuilder.writeListUint8(flex!);
    int? test5Offset;
    if (test5 != null) {
      for (var e in test5!) { e.pack(fbBuilder); }
      test5Offset = fbBuilder.endStructVector(test5!.length);
    }
    final int? vectorOfLongsOffset = vectorOfLongs == null ? null
        : fbBuilder.writeListInt64(vectorOfLongs!);
    final int? vectorOfDoublesOffset = vectorOfDoubles == null ? null
        : fbBuilder.writeListFloat64(vectorOfDoubles!);
    final int? parentNamespaceTestOffset = parentNamespaceTest?.pack(fbBuilder);
    final int? vectorOfReferrablesOffset = vectorOfReferrables == null ? null
        : fbBuilder.writeList(vectorOfReferrables!.map((b) => b.pack(fbBuilder)).toList());
    final int? vectorOfWeakReferencesOffset = vectorOfWeakReferences == null ? null
        : fbBuilder.writeListUint64(vectorOfWeakReferences!);
    final int? vectorOfStrongReferrablesOffset = vectorOfStrongReferrables == null ? null
        : fbBuilder.writeList(vectorOfStrongReferrables!.map((b) => b.pack(fbBuilder)).toList());
    final int? vectorOfCoOwningReferencesOffset = vectorOfCoOwningReferences == null ? null
        : fbBuilder.writeListUint64(vectorOfCoOwningReferences!);
    final int? vectorOfNonOwningReferencesOffset = vectorOfNonOwningReferences == null ? null
        : fbBuilder.writeListUint64(vectorOfNonOwningReferences!);
    final int? anyUniqueOffset = anyUnique?.pack(fbBuilder);
    final int? anyAmbiguousOffset = anyAmbiguous?.pack(fbBuilder);
    final int? vectorOfEnumsOffset = vectorOfEnums == null ? null
        : fbBuilder.writeListUint8(vectorOfEnums!.map((f) => f.value).toList());
    final int? testrequirednestedflatbufferOffset = testrequirednestedflatbuffer == null ? null
        : fbBuilder.writeListUint8(testrequirednestedflatbuffer!);
    final int? scalarKeySortedTablesOffset = scalarKeySortedTables == null ? null
        : fbBuilder.writeList(scalarKeySortedTables!.map((b) => b.pack(fbBuilder)).toList());
    fbBuilder.startTable(54);
    if (pos != null) {
      fbBuilder.addStruct(0, pos!.pack(fbBuilder));
    }
    fbBuilder.addInt16(1, mana);
    fbBuilder.addInt16(2, hp);
    fbBuilder.addOffset(3, nameOffset);
    fbBuilder.addOffset(5, inventoryOffset);
    fbBuilder.addUint8(6, color.value);
    fbBuilder.addUint8(7, testType?.value);
    fbBuilder.addOffset(8, testOffset);
    fbBuilder.addOffset(9, test4Offset);
    fbBuilder.addOffset(10, testarrayofstringOffset);
    fbBuilder.addOffset(11, testarrayoftablesOffset);
    fbBuilder.addOffset(12, enemyOffset);
    fbBuilder.addOffset(13, testnestedflatbufferOffset);
    fbBuilder.addOffset(14, testemptyOffset);
    fbBuilder.addBool(15, testbool);
    fbBuilder.addInt32(16, testhashs32Fnv1);
    fbBuilder.addUint32(17, testhashu32Fnv1);
    fbBuilder.addInt64(18, testhashs64Fnv1);
    fbBuilder.addUint64(19, testhashu64Fnv1);
    fbBuilder.addInt32(20, testhashs32Fnv1a);
    fbBuilder.addUint32(21, testhashu32Fnv1a);
    fbBuilder.addInt64(22, testhashs64Fnv1a);
    fbBuilder.addUint64(23, testhashu64Fnv1a);
    fbBuilder.addOffset(24, testarrayofboolsOffset);
    fbBuilder.addFloat32(25, testf);
    fbBuilder.addFloat32(26, testf2);
    fbBuilder.addFloat32(27, testf3);
    fbBuilder.addOffset(28, testarrayofstring2Offset);
    fbBuilder.addOffset(29, testarrayofsortedstructOffset);
    fbBuilder.addOffset(30, flexOffset);
    fbBuilder.addOffset(31, test5Offset);
    fbBuilder.addOffset(32, vectorOfLongsOffset);
    fbBuilder.addOffset(33, vectorOfDoublesOffset);
    fbBuilder.addOffset(34, parentNamespaceTestOffset);
    fbBuilder.addOffset(35, vectorOfReferrablesOffset);
    fbBuilder.addUint64(36, singleWeakReference);
    fbBuilder.addOffset(37, vectorOfWeakReferencesOffset);
    fbBuilder.addOffset(38, vectorOfStrongReferrablesOffset);
    fbBuilder.addUint64(39, coOwningReference);
    fbBuilder.addOffset(40, vectorOfCoOwningReferencesOffset);
    fbBuilder.addUint64(41, nonOwningReference);
    fbBuilder.addOffset(42, vectorOfNonOwningReferencesOffset);
    fbBuilder.addUint8(43, anyUniqueType?.value);
    fbBuilder.addOffset(44, anyUniqueOffset);
    fbBuilder.addUint8(45, anyAmbiguousType?.value);
    fbBuilder.addOffset(46, anyAmbiguousOffset);
    fbBuilder.addOffset(47, vectorOfEnumsOffset);
    fbBuilder.addInt8(48, signedEnum.value);
    fbBuilder.addOffset(49, testrequirednestedflatbufferOffset);
    fbBuilder.addOffset(50, scalarKeySortedTablesOffset);
    if (nativeInline != null) {
      fbBuilder.addStruct(51, nativeInline!.pack(fbBuilder));
    }
    fbBuilder.addUint64(52, longEnumNonEnumDefault.value);
    fbBuilder.addUint64(53, longEnumNormalDefault.value);
    return fbBuilder.endTable();
  }

  @override
  String toString() {
    return 'MonsterT{pos: ${pos}, mana: ${mana}, hp: ${hp}, name: ${name}, inventory: ${inventory}, color: ${color}, testType: ${testType}, test: ${test}, test4: ${test4}, testarrayofstring: ${testarrayofstring}, testarrayoftables: ${testarrayoftables}, enemy: ${enemy}, testnestedflatbuffer: ${testnestedflatbuffer}, testempty: ${testempty}, testbool: ${testbool}, testhashs32Fnv1: ${testhashs32Fnv1}, testhashu32Fnv1: ${testhashu32Fnv1}, testhashs64Fnv1: ${testhashs64Fnv1}, testhashu64Fnv1: ${testhashu64Fnv1}, testhashs32Fnv1a: ${testhashs32Fnv1a}, testhashu32Fnv1a: ${testhashu32Fnv1a}, testhashs64Fnv1a: ${testhashs64Fnv1a}, testhashu64Fnv1a: ${testhashu64Fnv1a}, testarrayofbools: ${testarrayofbools}, testf: ${testf}, testf2: ${testf2}, testf3: ${testf3}, testarrayofstring2: ${testarrayofstring2}, testarrayofsortedstruct: ${testarrayofsortedstruct}, flex: ${flex}, test5: ${test5}, vectorOfLongs: ${vectorOfLongs}, vectorOfDoubles: ${vectorOfDoubles}, parentNamespaceTest: ${parentNamespaceTest}, vectorOfReferrables: ${vectorOfReferrables}, singleWeakReference: ${singleWeakReference}, vectorOfWeakReferences: ${vectorOfWeakReferences}, vectorOfStrongReferrables: ${vectorOfStrongReferrables}, coOwningReference: ${coOwningReference}, vectorOfCoOwningReferences: ${vectorOfCoOwningReferences}, nonOwningReference: ${nonOwningReference}, vectorOfNonOwningReferences: ${vectorOfNonOwningReferences}, anyUniqueType: ${anyUniqueType}, anyUnique: ${anyUnique}, anyAmbiguousType: ${anyAmbiguousType}, anyAmbiguous: ${anyAmbiguous}, vectorOfEnums: ${vectorOfEnums}, signedEnum: ${signedEnum}, testrequirednestedflatbuffer: ${testrequirednestedflatbuffer}, scalarKeySortedTables: ${scalarKeySortedTables}, nativeInline: ${nativeInline}, longEnumNonEnumDefault: ${longEnumNonEnumDefault}, longEnumNormalDefault: ${longEnumNormalDefault}}';
  }
}

class _MonsterReader extends fb.TableReader<Monster> {
  const _MonsterReader();

  @override
  Monster createObject(fb.BufferContext bc, int offset) => 
    Monster._(bc, offset);
}

class MonsterBuilder {
  MonsterBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  void begin() {
    fbBuilder.startTable(54);
  }

  int addPos(int offset) {
    fbBuilder.addStruct(0, offset);
    return fbBuilder.offset;
  }
  int addMana(int? mana) {
    fbBuilder.addInt16(1, mana);
    return fbBuilder.offset;
  }
  int addHp(int? hp) {
    fbBuilder.addInt16(2, hp);
    return fbBuilder.offset;
  }
  int addNameOffset(int? offset) {
    fbBuilder.addOffset(3, offset);
    return fbBuilder.offset;
  }
  int addInventoryOffset(int? offset) {
    fbBuilder.addOffset(5, offset);
    return fbBuilder.offset;
  }
  int addColor(Color? color) {
    fbBuilder.addUint8(6, color?.value);
    return fbBuilder.offset;
  }
  int addTestType(AnyTypeId? testType) {
    fbBuilder.addUint8(7, testType?.value);
    return fbBuilder.offset;
  }
  int addTestOffset(int? offset) {
    fbBuilder.addOffset(8, offset);
    return fbBuilder.offset;
  }
  int addTest4Offset(int? offset) {
    fbBuilder.addOffset(9, offset);
    return fbBuilder.offset;
  }
  int addTestarrayofstringOffset(int? offset) {
    fbBuilder.addOffset(10, offset);
    return fbBuilder.offset;
  }
  int addTestarrayoftablesOffset(int? offset) {
    fbBuilder.addOffset(11, offset);
    return fbBuilder.offset;
  }
  int addEnemyOffset(int? offset) {
    fbBuilder.addOffset(12, offset);
    return fbBuilder.offset;
  }
  int addTestnestedflatbufferOffset(int? offset) {
    fbBuilder.addOffset(13, offset);
    return fbBuilder.offset;
  }
  int addTestemptyOffset(int? offset) {
    fbBuilder.addOffset(14, offset);
    return fbBuilder.offset;
  }
  int addTestbool(bool? testbool) {
    fbBuilder.addBool(15, testbool);
    return fbBuilder.offset;
  }
  int addTesthashs32Fnv1(int? testhashs32Fnv1) {
    fbBuilder.addInt32(16, testhashs32Fnv1);
    return fbBuilder.offset;
  }
  int addTesthashu32Fnv1(int? testhashu32Fnv1) {
    fbBuilder.addUint32(17, testhashu32Fnv1);
    return fbBuilder.offset;
  }
  int addTesthashs64Fnv1(int? testhashs64Fnv1) {
    fbBuilder.addInt64(18, testhashs64Fnv1);
    return fbBuilder.offset;
  }
  int addTesthashu64Fnv1(int? testhashu64Fnv1) {
    fbBuilder.addUint64(19, testhashu64Fnv1);
    return fbBuilder.offset;
  }
  int addTesthashs32Fnv1a(int? testhashs32Fnv1a) {
    fbBuilder.addInt32(20, testhashs32Fnv1a);
    return fbBuilder.offset;
  }
  int addTesthashu32Fnv1a(int? testhashu32Fnv1a) {
    fbBuilder.addUint32(21, testhashu32Fnv1a);
    return fbBuilder.offset;
  }
  int addTesthashs64Fnv1a(int? testhashs64Fnv1a) {
    fbBuilder.addInt64(22, testhashs64Fnv1a);
    return fbBuilder.offset;
  }
  int addTesthashu64Fnv1a(int? testhashu64Fnv1a) {
    fbBuilder.addUint64(23, testhashu64Fnv1a);
    return fbBuilder.offset;
  }
  int addTestarrayofboolsOffset(int? offset) {
    fbBuilder.addOffset(24, offset);
    return fbBuilder.offset;
  }
  int addTestf(double? testf) {
    fbBuilder.addFloat32(25, testf);
    return fbBuilder.offset;
  }
  int addTestf2(double? testf2) {
    fbBuilder.addFloat32(26, testf2);
    return fbBuilder.offset;
  }
  int addTestf3(double? testf3) {
    fbBuilder.addFloat32(27, testf3);
    return fbBuilder.offset;
  }
  int addTestarrayofstring2Offset(int? offset) {
    fbBuilder.addOffset(28, offset);
    return fbBuilder.offset;
  }
  int addTestarrayofsortedstructOffset(int? offset) {
    fbBuilder.addOffset(29, offset);
    return fbBuilder.offset;
  }
  int addFlexOffset(int? offset) {
    fbBuilder.addOffset(30, offset);
    return fbBuilder.offset;
  }
  int addTest5Offset(int? offset) {
    fbBuilder.addOffset(31, offset);
    return fbBuilder.offset;
  }
  int addVectorOfLongsOffset(int? offset) {
    fbBuilder.addOffset(32, offset);
    return fbBuilder.offset;
  }
  int addVectorOfDoublesOffset(int? offset) {
    fbBuilder.addOffset(33, offset);
    return fbBuilder.offset;
  }
  int addParentNamespaceTestOffset(int? offset) {
    fbBuilder.addOffset(34, offset);
    return fbBuilder.offset;
  }
  int addVectorOfReferrablesOffset(int? offset) {
    fbBuilder.addOffset(35, offset);
    return fbBuilder.offset;
  }
  int addSingleWeakReference(int? singleWeakReference) {
    fbBuilder.addUint64(36, singleWeakReference);
    return fbBuilder.offset;
  }
  int addVectorOfWeakReferencesOffset(int? offset) {
    fbBuilder.addOffset(37, offset);
    return fbBuilder.offset;
  }
  int addVectorOfStrongReferrablesOffset(int? offset) {
    fbBuilder.addOffset(38, offset);
    return fbBuilder.offset;
  }
  int addCoOwningReference(int? coOwningReference) {
    fbBuilder.addUint64(39, coOwningReference);
    return fbBuilder.offset;
  }
  int addVectorOfCoOwningReferencesOffset(int? offset) {
    fbBuilder.addOffset(40, offset);
    return fbBuilder.offset;
  }
  int addNonOwningReference(int? nonOwningReference) {
    fbBuilder.addUint64(41, nonOwningReference);
    return fbBuilder.offset;
  }
  int addVectorOfNonOwningReferencesOffset(int? offset) {
    fbBuilder.addOffset(42, offset);
    return fbBuilder.offset;
  }
  int addAnyUniqueType(AnyUniqueAliasesTypeId? anyUniqueType) {
    fbBuilder.addUint8(43, anyUniqueType?.value);
    return fbBuilder.offset;
  }
  int addAnyUniqueOffset(int? offset) {
    fbBuilder.addOffset(44, offset);
    return fbBuilder.offset;
  }
  int addAnyAmbiguousType(AnyAmbiguousAliasesTypeId? anyAmbiguousType) {
    fbBuilder.addUint8(45, anyAmbiguousType?.value);
    return fbBuilder.offset;
  }
  int addAnyAmbiguousOffset(int? offset) {
    fbBuilder.addOffset(46, offset);
    return fbBuilder.offset;
  }
  int addVectorOfEnumsOffset(int? offset) {
    fbBuilder.addOffset(47, offset);
    return fbBuilder.offset;
  }
  int addSignedEnum(Race? signedEnum) {
    fbBuilder.addInt8(48, signedEnum?.value);
    return fbBuilder.offset;
  }
  int addTestrequirednestedflatbufferOffset(int? offset) {
    fbBuilder.addOffset(49, offset);
    return fbBuilder.offset;
  }
  int addScalarKeySortedTablesOffset(int? offset) {
    fbBuilder.addOffset(50, offset);
    return fbBuilder.offset;
  }
  int addNativeInline(int offset) {
    fbBuilder.addStruct(51, offset);
    return fbBuilder.offset;
  }
  int addLongEnumNonEnumDefault(LongEnum? longEnumNonEnumDefault) {
    fbBuilder.addUint64(52, longEnumNonEnumDefault?.value);
    return fbBuilder.offset;
  }
  int addLongEnumNormalDefault(LongEnum? longEnumNormalDefault) {
    fbBuilder.addUint64(53, longEnumNormalDefault?.value);
    return fbBuilder.offset;
  }

  int finish() {
    return fbBuilder.endTable();
  }
}

class MonsterObjectBuilder extends fb.ObjectBuilder {
  final Vec3ObjectBuilder? _pos;
  final int? _mana;
  final int? _hp;
  final String? _name;
  final List<int>? _inventory;
  final Color? _color;
  final AnyTypeId? _testType;
  final dynamic _test;
  final List<TestObjectBuilder>? _test4;
  final List<String>? _testarrayofstring;
  final List<MonsterObjectBuilder>? _testarrayoftables;
  final MonsterObjectBuilder? _enemy;
  final List<int>? _testnestedflatbuffer;
  final StatObjectBuilder? _testempty;
  final bool? _testbool;
  final int? _testhashs32Fnv1;
  final int? _testhashu32Fnv1;
  final int? _testhashs64Fnv1;
  final int? _testhashu64Fnv1;
  final int? _testhashs32Fnv1a;
  final int? _testhashu32Fnv1a;
  final int? _testhashs64Fnv1a;
  final int? _testhashu64Fnv1a;
  final List<bool>? _testarrayofbools;
  final double? _testf;
  final double? _testf2;
  final double? _testf3;
  final List<String>? _testarrayofstring2;
  final List<AbilityObjectBuilder>? _testarrayofsortedstruct;
  final List<int>? _flex;
  final List<TestObjectBuilder>? _test5;
  final List<int>? _vectorOfLongs;
  final List<double>? _vectorOfDoubles;
  final my_game.InParentNamespaceObjectBuilder? _parentNamespaceTest;
  final List<ReferrableObjectBuilder>? _vectorOfReferrables;
  final int? _singleWeakReference;
  final List<int>? _vectorOfWeakReferences;
  final List<ReferrableObjectBuilder>? _vectorOfStrongReferrables;
  final int? _coOwningReference;
  final List<int>? _vectorOfCoOwningReferences;
  final int? _nonOwningReference;
  final List<int>? _vectorOfNonOwningReferences;
  final AnyUniqueAliasesTypeId? _anyUniqueType;
  final dynamic _anyUnique;
  final AnyAmbiguousAliasesTypeId? _anyAmbiguousType;
  final dynamic _anyAmbiguous;
  final List<Color>? _vectorOfEnums;
  final Race? _signedEnum;
  final List<int>? _testrequirednestedflatbuffer;
  final List<StatObjectBuilder>? _scalarKeySortedTables;
  final TestObjectBuilder? _nativeInline;
  final LongEnum? _longEnumNonEnumDefault;
  final LongEnum? _longEnumNormalDefault;

  MonsterObjectBuilder({
    Vec3ObjectBuilder? pos,
    int? mana,
    int? hp,
    String? name,
    List<int>? inventory,
    Color? color,
    AnyTypeId? testType,
    dynamic test,
    List<TestObjectBuilder>? test4,
    List<String>? testarrayofstring,
    List<MonsterObjectBuilder>? testarrayoftables,
    MonsterObjectBuilder? enemy,
    List<int>? testnestedflatbuffer,
    StatObjectBuilder? testempty,
    bool? testbool,
    int? testhashs32Fnv1,
    int? testhashu32Fnv1,
    int? testhashs64Fnv1,
    int? testhashu64Fnv1,
    int? testhashs32Fnv1a,
    int? testhashu32Fnv1a,
    int? testhashs64Fnv1a,
    int? testhashu64Fnv1a,
    List<bool>? testarrayofbools,
    double? testf,
    double? testf2,
    double? testf3,
    List<String>? testarrayofstring2,
    List<AbilityObjectBuilder>? testarrayofsortedstruct,
    List<int>? flex,
    List<TestObjectBuilder>? test5,
    List<int>? vectorOfLongs,
    List<double>? vectorOfDoubles,
    my_game.InParentNamespaceObjectBuilder? parentNamespaceTest,
    List<ReferrableObjectBuilder>? vectorOfReferrables,
    int? singleWeakReference,
    List<int>? vectorOfWeakReferences,
    List<ReferrableObjectBuilder>? vectorOfStrongReferrables,
    int? coOwningReference,
    List<int>? vectorOfCoOwningReferences,
    int? nonOwningReference,
    List<int>? vectorOfNonOwningReferences,
    AnyUniqueAliasesTypeId? anyUniqueType,
    dynamic anyUnique,
    AnyAmbiguousAliasesTypeId? anyAmbiguousType,
    dynamic anyAmbiguous,
    List<Color>? vectorOfEnums,
    Race? signedEnum,
    List<int>? testrequirednestedflatbuffer,
    List<StatObjectBuilder>? scalarKeySortedTables,
    TestObjectBuilder? nativeInline,
    LongEnum? longEnumNonEnumDefault,
    LongEnum? longEnumNormalDefault,
  })
      : _pos = pos,
        _mana = mana,
        _hp = hp,
        _name = name,
        _inventory = inventory,
        _color = color,
        _testType = testType,
        _test = test,
        _test4 = test4,
        _testarrayofstring = testarrayofstring,
        _testarrayoftables = testarrayoftables,
        _enemy = enemy,
        _testnestedflatbuffer = testnestedflatbuffer,
        _testempty = testempty,
        _testbool = testbool,
        _testhashs32Fnv1 = testhashs32Fnv1,
        _testhashu32Fnv1 = testhashu32Fnv1,
        _testhashs64Fnv1 = testhashs64Fnv1,
        _testhashu64Fnv1 = testhashu64Fnv1,
        _testhashs32Fnv1a = testhashs32Fnv1a,
        _testhashu32Fnv1a = testhashu32Fnv1a,
        _testhashs64Fnv1a = testhashs64Fnv1a,
        _testhashu64Fnv1a = testhashu64Fnv1a,
        _testarrayofbools = testarrayofbools,
        _testf = testf,
        _testf2 = testf2,
        _testf3 = testf3,
        _testarrayofstring2 = testarrayofstring2,
        _testarrayofsortedstruct = testarrayofsortedstruct,
        _flex = flex,
        _test5 = test5,
        _vectorOfLongs = vectorOfLongs,
        _vectorOfDoubles = vectorOfDoubles,
        _parentNamespaceTest = parentNamespaceTest,
        _vectorOfReferrables = vectorOfReferrables,
        _singleWeakReference = singleWeakReference,
        _vectorOfWeakReferences = vectorOfWeakReferences,
        _vectorOfStrongReferrables = vectorOfStrongReferrables,
        _coOwningReference = coOwningReference,
        _vectorOfCoOwningReferences = vectorOfCoOwningReferences,
        _nonOwningReference = nonOwningReference,
        _vectorOfNonOwningReferences = vectorOfNonOwningReferences,
        _anyUniqueType = anyUniqueType,
        _anyUnique = anyUnique,
        _anyAmbiguousType = anyAmbiguousType,
        _anyAmbiguous = anyAmbiguous,
        _vectorOfEnums = vectorOfEnums,
        _signedEnum = signedEnum,
        _testrequirednestedflatbuffer = testrequirednestedflatbuffer,
        _scalarKeySortedTables = scalarKeySortedTables,
        _nativeInline = nativeInline,
        _longEnumNonEnumDefault = longEnumNonEnumDefault,
        _longEnumNormalDefault = longEnumNormalDefault;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    final int? nameOffset = _name == null ? null
        : fbBuilder.writeString(_name!);
    final int? inventoryOffset = _inventory == null ? null
        : fbBuilder.writeListUint8(_inventory!);
    final int? testOffset = _test?.getOrCreateOffset(fbBuilder);
    final int? test4Offset = _test4 == null ? null
        : fbBuilder.writeListOfStructs(_test4!);
    final int? testarrayofstringOffset = _testarrayofstring == null ? null
        : fbBuilder.writeList(_testarrayofstring!.map(fbBuilder.writeString).toList());
    final int? testarrayoftablesOffset = _testarrayoftables == null ? null
        : fbBuilder.writeList(_testarrayoftables!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
    final int? enemyOffset = _enemy?.getOrCreateOffset(fbBuilder);
    final int? testnestedflatbufferOffset = _testnestedflatbuffer == null ? null
        : fbBuilder.writeListUint8(_testnestedflatbuffer!);
    final int? testemptyOffset = _testempty?.getOrCreateOffset(fbBuilder);
    final int? testarrayofboolsOffset = _testarrayofbools == null ? null
        : fbBuilder.writeListBool(_testarrayofbools!);
    final int? testarrayofstring2Offset = _testarrayofstring2 == null ? null
        : fbBuilder.writeList(_testarrayofstring2!.map(fbBuilder.writeString).toList());
    final int? testarrayofsortedstructOffset = _testarrayofsortedstruct == null ? null
        : fbBuilder.writeListOfStructs(_testarrayofsortedstruct!);
    final int? flexOffset = _flex == null ? null
        : fbBuilder.writeListUint8(_flex!);
    final int? test5Offset = _test5 == null ? null
        : fbBuilder.writeListOfStructs(_test5!);
    final int? vectorOfLongsOffset = _vectorOfLongs == null ? null
        : fbBuilder.writeListInt64(_vectorOfLongs!);
    final int? vectorOfDoublesOffset = _vectorOfDoubles == null ? null
        : fbBuilder.writeListFloat64(_vectorOfDoubles!);
    final int? parentNamespaceTestOffset = _parentNamespaceTest?.getOrCreateOffset(fbBuilder);
    final int? vectorOfReferrablesOffset = _vectorOfReferrables == null ? null
        : fbBuilder.writeList(_vectorOfReferrables!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
    final int? vectorOfWeakReferencesOffset = _vectorOfWeakReferences == null ? null
        : fbBuilder.writeListUint64(_vectorOfWeakReferences!);
    final int? vectorOfStrongReferrablesOffset = _vectorOfStrongReferrables == null ? null
        : fbBuilder.writeList(_vectorOfStrongReferrables!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
    final int? vectorOfCoOwningReferencesOffset = _vectorOfCoOwningReferences == null ? null
        : fbBuilder.writeListUint64(_vectorOfCoOwningReferences!);
    final int? vectorOfNonOwningReferencesOffset = _vectorOfNonOwningReferences == null ? null
        : fbBuilder.writeListUint64(_vectorOfNonOwningReferences!);
    final int? anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
    final int? anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
    final int? vectorOfEnumsOffset = _vectorOfEnums == null ? null
        : fbBuilder.writeListUint8(_vectorOfEnums!.map((f) => f.value).toList());
    final int? testrequirednestedflatbufferOffset = _testrequirednestedflatbuffer == null ? null
        : fbBuilder.writeListUint8(_testrequirednestedflatbuffer!);
    final int? scalarKeySortedTablesOffset = _scalarKeySortedTables == null ? null
        : fbBuilder.writeList(_scalarKeySortedTables!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
    fbBuilder.startTable(54);
    if (_pos != null) {
      fbBuilder.addStruct(0, _pos!.finish(fbBuilder));
    }
    fbBuilder.addInt16(1, _mana);
    fbBuilder.addInt16(2, _hp);
    fbBuilder.addOffset(3, nameOffset);
    fbBuilder.addOffset(5, inventoryOffset);
    fbBuilder.addUint8(6, _color?.value);
    fbBuilder.addUint8(7, _testType?.value);
    fbBuilder.addOffset(8, testOffset);
    fbBuilder.addOffset(9, test4Offset);
    fbBuilder.addOffset(10, testarrayofstringOffset);
    fbBuilder.addOffset(11, testarrayoftablesOffset);
    fbBuilder.addOffset(12, enemyOffset);
    fbBuilder.addOffset(13, testnestedflatbufferOffset);
    fbBuilder.addOffset(14, testemptyOffset);
    fbBuilder.addBool(15, _testbool);
    fbBuilder.addInt32(16, _testhashs32Fnv1);
    fbBuilder.addUint32(17, _testhashu32Fnv1);
    fbBuilder.addInt64(18, _testhashs64Fnv1);
    fbBuilder.addUint64(19, _testhashu64Fnv1);
    fbBuilder.addInt32(20, _testhashs32Fnv1a);
    fbBuilder.addUint32(21, _testhashu32Fnv1a);
    fbBuilder.addInt64(22, _testhashs64Fnv1a);
    fbBuilder.addUint64(23, _testhashu64Fnv1a);
    fbBuilder.addOffset(24, testarrayofboolsOffset);
    fbBuilder.addFloat32(25, _testf);
    fbBuilder.addFloat32(26, _testf2);
    fbBuilder.addFloat32(27, _testf3);
    fbBuilder.addOffset(28, testarrayofstring2Offset);
    fbBuilder.addOffset(29, testarrayofsortedstructOffset);
    fbBuilder.addOffset(30, flexOffset);
    fbBuilder.addOffset(31, test5Offset);
    fbBuilder.addOffset(32, vectorOfLongsOffset);
    fbBuilder.addOffset(33, vectorOfDoublesOffset);
    fbBuilder.addOffset(34, parentNamespaceTestOffset);
    fbBuilder.addOffset(35, vectorOfReferrablesOffset);
    fbBuilder.addUint64(36, _singleWeakReference);
    fbBuilder.addOffset(37, vectorOfWeakReferencesOffset);
    fbBuilder.addOffset(38, vectorOfStrongReferrablesOffset);
    fbBuilder.addUint64(39, _coOwningReference);
    fbBuilder.addOffset(40, vectorOfCoOwningReferencesOffset);
    fbBuilder.addUint64(41, _nonOwningReference);
    fbBuilder.addOffset(42, vectorOfNonOwningReferencesOffset);
    fbBuilder.addUint8(43, _anyUniqueType?.value);
    fbBuilder.addOffset(44, anyUniqueOffset);
    fbBuilder.addUint8(45, _anyAmbiguousType?.value);
    fbBuilder.addOffset(46, anyAmbiguousOffset);
    fbBuilder.addOffset(47, vectorOfEnumsOffset);
    fbBuilder.addInt8(48, _signedEnum?.value);
    fbBuilder.addOffset(49, testrequirednestedflatbufferOffset);
    fbBuilder.addOffset(50, scalarKeySortedTablesOffset);
    if (_nativeInline != null) {
      fbBuilder.addStruct(51, _nativeInline!.finish(fbBuilder));
    }
    fbBuilder.addUint64(52, _longEnumNonEnumDefault?.value);
    fbBuilder.addUint64(53, _longEnumNormalDefault?.value);
    return fbBuilder.endTable();
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
class TypeAliases {
  TypeAliases._(this._bc, this._bcOffset);
  factory TypeAliases(List<int> bytes) {
    final rootRef = fb.BufferContext.fromBytes(bytes);
    return reader.read(rootRef, 0);
  }

  static const fb.Reader<TypeAliases> reader = _TypeAliasesReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  int get i8 => const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 0);
  int get u8 => const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 6, 0);
  int get i16 => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 0);
  int get u16 => const fb.Uint16Reader().vTableGet(_bc, _bcOffset, 10, 0);
  int get i32 => const fb.Int32Reader().vTableGet(_bc, _bcOffset, 12, 0);
  int get u32 => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 14, 0);
  int get i64 => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 16, 0);
  int get u64 => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 18, 0);
  double get f32 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 20, 0.0);
  double get f64 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 22, 0.0);
  List<int>? get v8 => const fb.Int8ListReader().vTableGetNullable(_bc, _bcOffset, 24);
  List<double>? get vf64 => const fb.ListReader<double>(fb.Float64Reader()).vTableGetNullable(_bc, _bcOffset, 26);

  @override
  String toString() {
    return 'TypeAliases{i8: ${i8}, u8: ${u8}, i16: ${i16}, u16: ${u16}, i32: ${i32}, u32: ${u32}, i64: ${i64}, u64: ${u64}, f32: ${f32}, f64: ${f64}, v8: ${v8}, vf64: ${vf64}}';
  }

  TypeAliasesT unpack() => TypeAliasesT(
      i8: i8,
      u8: u8,
      i16: i16,
      u16: u16,
      i32: i32,
      u32: u32,
      i64: i64,
      u64: u64,
      f32: f32,
      f64: f64,
      v8: const fb.Int8ListReader(lazy: false).vTableGetNullable(_bc, _bcOffset, 24),
      vf64: const fb.ListReader<double>(fb.Float64Reader(), lazy: false).vTableGetNullable(_bc, _bcOffset, 26));

  static int pack(fb.Builder fbBuilder, TypeAliasesT? object) {
    if (object == null) return 0;
    return object.pack(fbBuilder);
  }
}

class TypeAliasesT implements fb.Packable {
  int i8;
  int u8;
  int i16;
  int u16;
  int i32;
  int u32;
  int i64;
  int u64;
  double f32;
  double f64;
  List<int>? v8;
  List<double>? vf64;

  TypeAliasesT({
      this.i8 = 0,
      this.u8 = 0,
      this.i16 = 0,
      this.u16 = 0,
      this.i32 = 0,
      this.u32 = 0,
      this.i64 = 0,
      this.u64 = 0,
      this.f32 = 0.0,
      this.f64 = 0.0,
      this.v8,
      this.vf64});

  @override
  int pack(fb.Builder fbBuilder) {
    final int? v8Offset = v8 == null ? null
        : fbBuilder.writeListInt8(v8!);
    final int? vf64Offset = vf64 == null ? null
        : fbBuilder.writeListFloat64(vf64!);
    fbBuilder.startTable(12);
    fbBuilder.addInt8(0, i8);
    fbBuilder.addUint8(1, u8);
    fbBuilder.addInt16(2, i16);
    fbBuilder.addUint16(3, u16);
    fbBuilder.addInt32(4, i32);
    fbBuilder.addUint32(5, u32);
    fbBuilder.addInt64(6, i64);
    fbBuilder.addUint64(7, u64);
    fbBuilder.addFloat32(8, f32);
    fbBuilder.addFloat64(9, f64);
    fbBuilder.addOffset(10, v8Offset);
    fbBuilder.addOffset(11, vf64Offset);
    return fbBuilder.endTable();
  }

  @override
  String toString() {
    return 'TypeAliasesT{i8: ${i8}, u8: ${u8}, i16: ${i16}, u16: ${u16}, i32: ${i32}, u32: ${u32}, i64: ${i64}, u64: ${u64}, f32: ${f32}, f64: ${f64}, v8: ${v8}, vf64: ${vf64}}';
  }
}

class _TypeAliasesReader extends fb.TableReader<TypeAliases> {
  const _TypeAliasesReader();

  @override
  TypeAliases createObject(fb.BufferContext bc, int offset) => 
    TypeAliases._(bc, offset);
}

class TypeAliasesBuilder {
  TypeAliasesBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

  void begin() {
    fbBuilder.startTable(12);
  }

  int addI8(int? i8) {
    fbBuilder.addInt8(0, i8);
    return fbBuilder.offset;
  }
  int addU8(int? u8) {
    fbBuilder.addUint8(1, u8);
    return fbBuilder.offset;
  }
  int addI16(int? i16) {
    fbBuilder.addInt16(2, i16);
    return fbBuilder.offset;
  }
  int addU16(int? u16) {
    fbBuilder.addUint16(3, u16);
    return fbBuilder.offset;
  }
  int addI32(int? i32) {
    fbBuilder.addInt32(4, i32);
    return fbBuilder.offset;
  }
  int addU32(int? u32) {
    fbBuilder.addUint32(5, u32);
    return fbBuilder.offset;
  }
  int addI64(int? i64) {
    fbBuilder.addInt64(6, i64);
    return fbBuilder.offset;
  }
  int addU64(int? u64) {
    fbBuilder.addUint64(7, u64);
    return fbBuilder.offset;
  }
  int addF32(double? f32) {
    fbBuilder.addFloat32(8, f32);
    return fbBuilder.offset;
  }
  int addF64(double? f64) {
    fbBuilder.addFloat64(9, f64);
    return fbBuilder.offset;
  }
  int addV8Offset(int? offset) {
    fbBuilder.addOffset(10, offset);
    return fbBuilder.offset;
  }
  int addVf64Offset(int? offset) {
    fbBuilder.addOffset(11, offset);
    return fbBuilder.offset;
  }

  int finish() {
    return fbBuilder.endTable();
  }
}

class TypeAliasesObjectBuilder extends fb.ObjectBuilder {
  final int? _i8;
  final int? _u8;
  final int? _i16;
  final int? _u16;
  final int? _i32;
  final int? _u32;
  final int? _i64;
  final int? _u64;
  final double? _f32;
  final double? _f64;
  final List<int>? _v8;
  final List<double>? _vf64;

  TypeAliasesObjectBuilder({
    int? i8,
    int? u8,
    int? i16,
    int? u16,
    int? i32,
    int? u32,
    int? i64,
    int? u64,
    double? f32,
    double? f64,
    List<int>? v8,
    List<double>? vf64,
  })
      : _i8 = i8,
        _u8 = u8,
        _i16 = i16,
        _u16 = u16,
        _i32 = i32,
        _u32 = u32,
        _i64 = i64,
        _u64 = u64,
        _f32 = f32,
        _f64 = f64,
        _v8 = v8,
        _vf64 = vf64;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    final int? v8Offset = _v8 == null ? null
        : fbBuilder.writeListInt8(_v8!);
    final int? vf64Offset = _vf64 == null ? null
        : fbBuilder.writeListFloat64(_vf64!);
    fbBuilder.startTable(12);
    fbBuilder.addInt8(0, _i8);
    fbBuilder.addUint8(1, _u8);
    fbBuilder.addInt16(2, _i16);
    fbBuilder.addUint16(3, _u16);
    fbBuilder.addInt32(4, _i32);
    fbBuilder.addUint32(5, _u32);
    fbBuilder.addInt64(6, _i64);
    fbBuilder.addUint64(7, _u64);
    fbBuilder.addFloat32(8, _f32);
    fbBuilder.addFloat64(9, _f64);
    fbBuilder.addOffset(10, v8Offset);
    fbBuilder.addOffset(11, vf64Offset);
    return fbBuilder.endTable();
  }

  /// Convenience method to serialize to byte list.
  @override
  Uint8List toBytes([String? fileIdentifier]) {
    final fbBuilder = fb.Builder(deduplicateTables: false);
    fbBuilder.finish(finish(fbBuilder), fileIdentifier);
    return fbBuilder.buffer;
  }
}
