// 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';
/**
 * File specific information.
 * Symbols declared within a file may be recovered by iterating over all
 * symbols and examining the `declaration_file` field.
 */
export class SchemaFile {
  constructor() {
    this.bb = null;
    this.bb_pos = 0;
  }
  __init(i, bb) {
    this.bb_pos = i;
    this.bb = bb;
    return this;
  }
  static getRootAsSchemaFile(bb, obj) {
    return (obj || new SchemaFile())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  static getSizePrefixedRootAsSchemaFile(bb, obj) {
    bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
    return (obj || new SchemaFile())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  filename(optionalEncoding) {
    const offset = this.bb.__offset(this.bb_pos, 4);
    return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) :
                    null;
  }
  includedFilenames(index, optionalEncoding) {
    const offset = this.bb.__offset(this.bb_pos, 6);
    return offset ? this.bb.__string(
                        this.bb.__vector(this.bb_pos + offset) + index * 4,
                        optionalEncoding) :
                    null;
  }
  includedFilenamesLength() {
    const offset = this.bb.__offset(this.bb_pos, 6);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  static getFullyQualifiedName() {
    return 'reflection.SchemaFile';
  }
  static startSchemaFile(builder) {
    builder.startObject(2);
  }
  static addFilename(builder, filenameOffset) {
    builder.addFieldOffset(0, filenameOffset, 0);
  }
  static addIncludedFilenames(builder, includedFilenamesOffset) {
    builder.addFieldOffset(1, includedFilenamesOffset, 0);
  }
  static createIncludedFilenamesVector(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 startIncludedFilenamesVector(builder, numElems) {
    builder.startVector(4, numElems, 4);
  }
  static endSchemaFile(builder) {
    const offset = builder.endObject();
    builder.requiredField(offset, 4);  // filename
    return offset;
  }
  static createSchemaFile(builder, filenameOffset, includedFilenamesOffset) {
    SchemaFile.startSchemaFile(builder);
    SchemaFile.addFilename(builder, filenameOffset);
    SchemaFile.addIncludedFilenames(builder, includedFilenamesOffset);
    return SchemaFile.endSchemaFile(builder);
  }
  unpack() {
    return new SchemaFileT(
        this.filename(),
        this.bb.createScalarList(
            this.includedFilenames.bind(this), this.includedFilenamesLength()));
  }
  unpackTo(_o) {
    _o.filename = this.filename();
    _o.includedFilenames = this.bb.createScalarList(
        this.includedFilenames.bind(this), this.includedFilenamesLength());
  }
}
export class SchemaFileT {
  constructor(filename = null, includedFilenames = []) {
    this.filename = filename;
    this.includedFilenames = includedFilenames;
  }
  pack(builder) {
    const filename =
        (this.filename !== null ? builder.createString(this.filename) : 0);
    const includedFilenames = SchemaFile.createIncludedFilenamesVector(
        builder, builder.createObjectOffsetList(this.includedFilenames));
    return SchemaFile.createSchemaFile(builder, filename, includedFilenames);
  }
}
