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

import 'dart:typed_data' show Uint8List;

import 'package:flat_buffers/flat_buffers.dart' as fb;

enum OptionsEnum {
  A(1),
  B(2),
  C(3);

  final int value;
  const OptionsEnum(this.value);

  factory OptionsEnum.fromValue(int value) {
    switch (value) {
      case 1:
        return OptionsEnum.A;
      case 2:
        return OptionsEnum.B;
      case 3:
        return OptionsEnum.C;
      default:
        throw StateError('Invalid value $value for bit flag enum');
    }
  }

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

  static const int minValue = 1;
  static const int maxValue = 3;
  static const fb.Reader<OptionsEnum> reader = _OptionsEnumReader();
}

class _OptionsEnumReader extends fb.Reader<OptionsEnum> {
  const _OptionsEnumReader();

  @override
  int get size => 4;

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

class MyTable {
  MyTable._(this._bc, this._bcOffset);
  factory MyTable(List<int> bytes) {
    final rootRef = fb.BufferContext.fromBytes(bytes);
    return reader.read(rootRef, 0);
  }

  static const fb.Reader<MyTable> reader = _MyTableReader();

  final fb.BufferContext _bc;
  final int _bcOffset;

  List<OptionsEnum>? get options => const fb.ListReader<OptionsEnum>(
    OptionsEnum.reader,
  ).vTableGetNullable(_bc, _bcOffset, 4);

  @override
  String toString() {
    return 'MyTable{options: ${options}}';
  }

  MyTableT unpack() => MyTableT(
    options: const fb.ListReader<OptionsEnum>(
      OptionsEnum.reader,
      lazy: false,
    ).vTableGetNullable(_bc, _bcOffset, 4),
  );

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

class MyTableT implements fb.Packable {
  List<OptionsEnum>? options;

  MyTableT({this.options});

  @override
  int pack(fb.Builder fbBuilder) {
    final int? optionsOffset = options == null
        ? null
        : fbBuilder.writeListUint32(options!.map((f) => f.value).toList());
    fbBuilder.startTable(1);
    fbBuilder.addOffset(0, optionsOffset);
    return fbBuilder.endTable();
  }

  @override
  String toString() {
    return 'MyTableT{options: ${options}}';
  }
}

class _MyTableReader extends fb.TableReader<MyTable> {
  const _MyTableReader();

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

class MyTableBuilder {
  MyTableBuilder(this.fbBuilder);

  final fb.Builder fbBuilder;

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

  int addOptionsOffset(int? offset) {
    fbBuilder.addOffset(0, offset);
    return fbBuilder.offset;
  }

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

class MyTableObjectBuilder extends fb.ObjectBuilder {
  final List<OptionsEnum>? _options;

  MyTableObjectBuilder({List<OptionsEnum>? options}) : _options = options;

  /// Finish building, and store into the [fbBuilder].
  @override
  int finish(fb.Builder fbBuilder) {
    final int? optionsOffset = _options == null
        ? null
        : fbBuilder.writeListUint32(_options!.map((f) => f.value).toList());
    fbBuilder.startTable(1);
    fbBuilder.addOffset(0, optionsOffset);
    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;
  }
}
