// automatically generated by the FlatBuffers compiler, do not modify

/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */

import * as flatbuffers from 'flatbuffers';

import {TableB, TableBT} from './my-game/other-name-space/table-b.js';

export class TableA implements flatbuffers.IUnpackableObject<TableAT> {
  bb: flatbuffers.ByteBuffer | null = null;
  bb_pos = 0;
  __init(i: number, bb: flatbuffers.ByteBuffer): TableA {
    this.bb_pos = i;
    this.bb = bb;
    return this;
  }

  static getRootAsTableA(bb: flatbuffers.ByteBuffer, obj?: TableA): TableA {
    return (obj || new TableA()).__init(
      bb.readInt32(bb.position()) + bb.position(),
      bb,
    );
  }

  static getSizePrefixedRootAsTableA(
    bb: flatbuffers.ByteBuffer,
    obj?: TableA,
  ): TableA {
    bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
    return (obj || new TableA()).__init(
      bb.readInt32(bb.position()) + bb.position(),
      bb,
    );
  }

  b(obj?: TableB): TableB | null {
    const offset = this.bb!.__offset(this.bb_pos, 4);
    return offset
      ? (obj || new TableB()).__init(
          this.bb!.__indirect(this.bb_pos + offset),
          this.bb!,
        )
      : null;
  }

  static getFullyQualifiedName(): string {
    return 'TableA';
  }

  static startTableA(builder: flatbuffers.Builder) {
    builder.startObject(1);
  }

  static addB(builder: flatbuffers.Builder, bOffset: flatbuffers.Offset) {
    builder.addFieldOffset(0, bOffset, 0);
  }

  static endTableA(builder: flatbuffers.Builder): flatbuffers.Offset {
    const offset = builder.endObject();
    return offset;
  }

  static createTableA(
    builder: flatbuffers.Builder,
    bOffset: flatbuffers.Offset,
  ): flatbuffers.Offset {
    TableA.startTableA(builder);
    TableA.addB(builder, bOffset);
    return TableA.endTableA(builder);
  }

  serialize(): Uint8Array {
    return this.bb!.bytes();
  }

  static deserialize(buffer: Uint8Array): TableA {
    return TableA.getRootAsTableA(new flatbuffers.ByteBuffer(buffer));
  }

  unpack(): TableAT {
    return new TableAT(this.b() !== null ? this.b()!.unpack() : null);
  }

  unpackTo(_o: TableAT): void {
    _o.b = this.b() !== null ? this.b()!.unpack() : null;
  }
}

export class TableAT implements flatbuffers.IGeneratedObject {
  constructor(public b: TableBT | null = null) {}

  pack(builder: flatbuffers.Builder): flatbuffers.Offset {
    const b = this.b !== null ? this.b!.pack(builder) : 0;

    return TableA.createTableA(builder, b);
  }
}
