// 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);
    }
}
