# automatically generated by the FlatBuffers compiler, do not modify

# namespace: tosa

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

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

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

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

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

    # ResizeAttribute
    def Mode(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
        return 0

def ResizeAttributeStart(builder):
    builder.StartObject(4)

def Start(builder):
    ResizeAttributeStart(builder)

def ResizeAttributeAddMode(builder, mode):
    builder.PrependUint32Slot(3, mode, 0)

def AddMode(builder, mode):
    ResizeAttributeAddMode(builder, mode)

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

def End(builder):
    return ResizeAttributeEnd(builder)
