// 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 {Enum} from '../reflection/enum.js';
import {Object_} from '../reflection/object.js';
import {SchemaFile} from '../reflection/schema-file.js';
import {Service} from '../reflection/service.js';

export class Schema {
  constructor() {
    this.bb = null;
    this.bb_pos = 0;
  }
  __init(i, bb) {
    this.bb_pos = i;
    this.bb = bb;
    return this;
  }
  static getRootAsSchema(bb, obj) {
    return (obj || new Schema())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  static getSizePrefixedRootAsSchema(bb, obj) {
    bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
    return (obj || new Schema())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  static bufferHasIdentifier(bb) {
    return bb.__has_identifier('BFBS');
  }
  objects(index, obj) {
    const offset = this.bb.__offset(this.bb_pos, 4);
    return offset ?
        (obj || new Object_())
            .__init(
                this.bb.__indirect(
                    this.bb.__vector(this.bb_pos + offset) + index * 4),
                this.bb) :
        null;
  }
  objectsLength() {
    const offset = this.bb.__offset(this.bb_pos, 4);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  enums(index, obj) {
    const offset = this.bb.__offset(this.bb_pos, 6);
    return offset ?
        (obj || new Enum())
            .__init(
                this.bb.__indirect(
                    this.bb.__vector(this.bb_pos + offset) + index * 4),
                this.bb) :
        null;
  }
  enumsLength() {
    const offset = this.bb.__offset(this.bb_pos, 6);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  fileIdent(optionalEncoding) {
    const offset = this.bb.__offset(this.bb_pos, 8);
    return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) :
                    null;
  }
  fileExt(optionalEncoding) {
    const offset = this.bb.__offset(this.bb_pos, 10);
    return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) :
                    null;
  }
  rootTable(obj) {
    const offset = this.bb.__offset(this.bb_pos, 12);
    return offset ?
        (obj || new Object_())
            .__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
        null;
  }
  services(index, obj) {
    const offset = this.bb.__offset(this.bb_pos, 14);
    return offset ?
        (obj || new Service())
            .__init(
                this.bb.__indirect(
                    this.bb.__vector(this.bb_pos + offset) + index * 4),
                this.bb) :
        null;
  }
  servicesLength() {
    const offset = this.bb.__offset(this.bb_pos, 14);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  advancedFeatures() {
    const offset = this.bb.__offset(this.bb_pos, 16);
    return offset ? this.bb.readUint64(this.bb_pos + offset) : BigInt('0');
  }
  mutate_advanced_features(value) {
    const offset = this.bb.__offset(this.bb_pos, 16);
    if (offset === 0) {
      return false;
    }
    this.bb.writeUint64(this.bb_pos + offset, value);
    return true;
  }
  /**
   * All the files used in this compilation. Files are relative to where
   * flatc was invoked.
   */
  fbsFiles(index, obj) {
    const offset = this.bb.__offset(this.bb_pos, 18);
    return offset ?
        (obj || new SchemaFile())
            .__init(
                this.bb.__indirect(
                    this.bb.__vector(this.bb_pos + offset) + index * 4),
                this.bb) :
        null;
  }
  fbsFilesLength() {
    const offset = this.bb.__offset(this.bb_pos, 18);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  static getFullyQualifiedName() {
    return 'reflection.Schema';
  }
  static startSchema(builder) {
    builder.startObject(8);
  }
  static addObjects(builder, objectsOffset) {
    builder.addFieldOffset(0, objectsOffset, 0);
  }
  static createObjectsVector(builder, data) {
    builder.startVector(4, data.length, 4);
    for (let i = data.length - 1; i >= 0; i--) {
      builder.addOffset(data[i]);
    }
    return builder.endVector();
  }
  static startObjectsVector(builder, numElems) {
    builder.startVector(4, numElems, 4);
  }
  static addEnums(builder, enumsOffset) {
    builder.addFieldOffset(1, enumsOffset, 0);
  }
  static createEnumsVector(builder, data) {
    builder.startVector(4, data.length, 4);
    for (let i = data.length - 1; i >= 0; i--) {
      builder.addOffset(data[i]);
    }
    return builder.endVector();
  }
  static startEnumsVector(builder, numElems) {
    builder.startVector(4, numElems, 4);
  }
  static addFileIdent(builder, fileIdentOffset) {
    builder.addFieldOffset(2, fileIdentOffset, 0);
  }
  static addFileExt(builder, fileExtOffset) {
    builder.addFieldOffset(3, fileExtOffset, 0);
  }
  static addRootTable(builder, rootTableOffset) {
    builder.addFieldOffset(4, rootTableOffset, 0);
  }
  static addServices(builder, servicesOffset) {
    builder.addFieldOffset(5, servicesOffset, 0);
  }
  static createServicesVector(builder, data) {
    builder.startVector(4, data.length, 4);
    for (let i = data.length - 1; i >= 0; i--) {
      builder.addOffset(data[i]);
    }
    return builder.endVector();
  }
  static startServicesVector(builder, numElems) {
    builder.startVector(4, numElems, 4);
  }
  static addAdvancedFeatures(builder, advancedFeatures) {
    builder.addFieldInt64(6, advancedFeatures, BigInt('0'));
  }
  static addFbsFiles(builder, fbsFilesOffset) {
    builder.addFieldOffset(7, fbsFilesOffset, 0);
  }
  static createFbsFilesVector(builder, data) {
    builder.startVector(4, data.length, 4);
    for (let i = data.length - 1; i >= 0; i--) {
      builder.addOffset(data[i]);
    }
    return builder.endVector();
  }
  static startFbsFilesVector(builder, numElems) {
    builder.startVector(4, numElems, 4);
  }
  static endSchema(builder) {
    const offset = builder.endObject();
    builder.requiredField(offset, 4);  // objects
    builder.requiredField(offset, 6);  // enums
    return offset;
  }
  static finishSchemaBuffer(builder, offset) {
    builder.finish(offset, 'BFBS');
  }
  static finishSizePrefixedSchemaBuffer(builder, offset) {
    builder.finish(offset, 'BFBS', true);
  }
  unpack() {
    return new SchemaT(
        this.bb.createObjList(this.objects.bind(this), this.objectsLength()),
        this.bb.createObjList(this.enums.bind(this), this.enumsLength()),
        this.fileIdent(), this.fileExt(),
        (this.rootTable() !== null ? this.rootTable().unpack() : null),
        this.bb.createObjList(this.services.bind(this), this.servicesLength()),
        this.advancedFeatures(),
        this.bb.createObjList(this.fbsFiles.bind(this), this.fbsFilesLength()));
  }
  unpackTo(_o) {
    _o.objects =
        this.bb.createObjList(this.objects.bind(this), this.objectsLength());
    _o.enums = this.bb.createObjList(this.enums.bind(this), this.enumsLength());
    _o.fileIdent = this.fileIdent();
    _o.fileExt = this.fileExt();
    _o.rootTable =
        (this.rootTable() !== null ? this.rootTable().unpack() : null);
    _o.services =
        this.bb.createObjList(this.services.bind(this), this.servicesLength());
    _o.advancedFeatures = this.advancedFeatures();
    _o.fbsFiles =
        this.bb.createObjList(this.fbsFiles.bind(this), this.fbsFilesLength());
  }
}
export class SchemaT {
  constructor(
      objects = [], enums = [], fileIdent = null, fileExt = null,
      rootTable = null, services = [], advancedFeatures = BigInt('0'),
      fbsFiles = []) {
    this.objects = objects;
    this.enums = enums;
    this.fileIdent = fileIdent;
    this.fileExt = fileExt;
    this.rootTable = rootTable;
    this.services = services;
    this.advancedFeatures = advancedFeatures;
    this.fbsFiles = fbsFiles;
  }
  pack(builder) {
    const objects = Schema.createObjectsVector(
        builder, builder.createObjectOffsetList(this.objects));
    const enums = Schema.createEnumsVector(
        builder, builder.createObjectOffsetList(this.enums));
    const fileIdent =
        (this.fileIdent !== null ? builder.createString(this.fileIdent) : 0);
    const fileExt =
        (this.fileExt !== null ? builder.createString(this.fileExt) : 0);
    const rootTable =
        (this.rootTable !== null ? this.rootTable.pack(builder) : 0);
    const services = Schema.createServicesVector(
        builder, builder.createObjectOffsetList(this.services));
    const fbsFiles = Schema.createFbsFilesVector(
        builder, builder.createObjectOffsetList(this.fbsFiles));
    Schema.startSchema(builder);
    Schema.addObjects(builder, objects);
    Schema.addEnums(builder, enums);
    Schema.addFileIdent(builder, fileIdent);
    Schema.addFileExt(builder, fileExt);
    Schema.addRootTable(builder, rootTable);
    Schema.addServices(builder, services);
    Schema.addAdvancedFeatures(builder, this.advancedFeatures);
    Schema.addFbsFiles(builder, fbsFiles);
    return Schema.endSchema(builder);
  }
}
