// 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 {KeyValue} from '../reflection/key-value.js';
import {Type} from '../reflection/type.js';

export class EnumVal {
  constructor() {
    this.bb = null;
    this.bb_pos = 0;
  }
  __init(i, bb) {
    this.bb_pos = i;
    this.bb = bb;
    return this;
  }
  static getRootAsEnumVal(bb, obj) {
    return (obj || new EnumVal())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  static getSizePrefixedRootAsEnumVal(bb, obj) {
    bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
    return (obj || new EnumVal())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  name(optionalEncoding) {
    const offset = this.bb.__offset(this.bb_pos, 4);
    return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) :
                    null;
  }
  value() {
    const offset = this.bb.__offset(this.bb_pos, 6);
    return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt('0');
  }
  mutate_value(value) {
    const offset = this.bb.__offset(this.bb_pos, 6);
    if (offset === 0) {
      return false;
    }
    this.bb.writeInt64(this.bb_pos + offset, value);
    return true;
  }
  unionType(obj) {
    const offset = this.bb.__offset(this.bb_pos, 10);
    return offset ?
        (obj || new Type())
            .__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
        null;
  }
  documentation(index, optionalEncoding) {
    const offset = this.bb.__offset(this.bb_pos, 12);
    return offset ? this.bb.__string(
                        this.bb.__vector(this.bb_pos + offset) + index * 4,
                        optionalEncoding) :
                    null;
  }
  documentationLength() {
    const offset = this.bb.__offset(this.bb_pos, 12);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  attributes(index, obj) {
    const offset = this.bb.__offset(this.bb_pos, 14);
    return offset ?
        (obj || new KeyValue())
            .__init(
                this.bb.__indirect(
                    this.bb.__vector(this.bb_pos + offset) + index * 4),
                this.bb) :
        null;
  }
  attributesLength() {
    const offset = this.bb.__offset(this.bb_pos, 14);
    return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
  }
  static getFullyQualifiedName() {
    return 'reflection.EnumVal';
  }
  static startEnumVal(builder) {
    builder.startObject(6);
  }
  static addName(builder, nameOffset) {
    builder.addFieldOffset(0, nameOffset, 0);
  }
  static addValue(builder, value) {
    builder.addFieldInt64(1, value, BigInt('0'));
  }
  static addUnionType(builder, unionTypeOffset) {
    builder.addFieldOffset(3, unionTypeOffset, 0);
  }
  static addDocumentation(builder, documentationOffset) {
    builder.addFieldOffset(4, documentationOffset, 0);
  }
  static createDocumentationVector(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 startDocumentationVector(builder, numElems) {
    builder.startVector(4, numElems, 4);
  }
  static addAttributes(builder, attributesOffset) {
    builder.addFieldOffset(5, attributesOffset, 0);
  }
  static createAttributesVector(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 startAttributesVector(builder, numElems) {
    builder.startVector(4, numElems, 4);
  }
  static endEnumVal(builder) {
    const offset = builder.endObject();
    builder.requiredField(offset, 4);  // name
    return offset;
  }
  unpack() {
    return new EnumValT(
        this.name(), this.value(),
        (this.unionType() !== null ? this.unionType().unpack() : null),
        this.bb.createScalarList(
            this.documentation.bind(this), this.documentationLength()),
        this.bb.createObjList(
            this.attributes.bind(this), this.attributesLength()));
  }
  unpackTo(_o) {
    _o.name = this.name();
    _o.value = this.value();
    _o.unionType =
        (this.unionType() !== null ? this.unionType().unpack() : null);
    _o.documentation = this.bb.createScalarList(
        this.documentation.bind(this), this.documentationLength());
    _o.attributes = this.bb.createObjList(
        this.attributes.bind(this), this.attributesLength());
  }
}
export class EnumValT {
  constructor(
      name = null, value = BigInt('0'), unionType = null, documentation = [],
      attributes = []) {
    this.name = name;
    this.value = value;
    this.unionType = unionType;
    this.documentation = documentation;
    this.attributes = attributes;
  }
  pack(builder) {
    const name = (this.name !== null ? builder.createString(this.name) : 0);
    const unionType =
        (this.unionType !== null ? this.unionType.pack(builder) : 0);
    const documentation = EnumVal.createDocumentationVector(
        builder, builder.createObjectOffsetList(this.documentation));
    const attributes = EnumVal.createAttributesVector(
        builder, builder.createObjectOffsetList(this.attributes));
    EnumVal.startEnumVal(builder);
    EnumVal.addName(builder, name);
    EnumVal.addValue(builder, this.value);
    EnumVal.addUnionType(builder, unionType);
    EnumVal.addDocumentation(builder, documentation);
    EnumVal.addAttributes(builder, attributes);
    return EnumVal.endEnumVal(builder);
  }
}
