# automatically generated by the FlatBuffers compiler, do not modify

# namespace: tosa

import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()

class PadAttribute(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = PadAttribute()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsPadAttribute(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def PadAttributeBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x54\x4F\x53\x41", size_prefixed=size_prefixed)

    # PadAttribute
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # PadAttribute
    def PadConst(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # PadAttribute
    def PadConstAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # PadAttribute
    def PadConstLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # PadAttribute
    def PadConstIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        return o == 0

def PadAttributeStart(builder):
    builder.StartObject(1)

def Start(builder):
    PadAttributeStart(builder)

def PadAttributeAddPadConst(builder, padConst):
    builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(padConst), 0)

def AddPadConst(builder, padConst):
    PadAttributeAddPadConst(builder, padConst)

def PadAttributeStartPadConstVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartPadConstVector(builder, numElems: int) -> int:
    return PadAttributeStartPadConstVector(builder, numElems)

def PadAttributeEnd(builder):
    return builder.EndObject()

def End(builder):
    return PadAttributeEnd(builder)
