# automatically generated by the FlatBuffers compiler, do not modify

# namespace: tflite

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

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

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

    @classmethod
    def GetRootAsStridedSliceOptions(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def StridedSliceOptionsBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x54\x46\x4C\x33", size_prefixed=size_prefixed)

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

    # StridedSliceOptions
    def BeginMask(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # StridedSliceOptions
    def EndMask(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # StridedSliceOptions
    def EllipsisMask(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

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

    # StridedSliceOptions
    def ShrinkAxisMask(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # StridedSliceOptions
    def Offset(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
        return False

def StridedSliceOptionsStart(builder): builder.StartObject(6)
def Start(builder):
    return StridedSliceOptionsStart(builder)
def StridedSliceOptionsAddBeginMask(builder, beginMask): builder.PrependInt32Slot(0, beginMask, 0)
def AddBeginMask(builder, beginMask):
    return StridedSliceOptionsAddBeginMask(builder, beginMask)
def StridedSliceOptionsAddEndMask(builder, endMask): builder.PrependInt32Slot(1, endMask, 0)
def AddEndMask(builder, endMask):
    return StridedSliceOptionsAddEndMask(builder, endMask)
def StridedSliceOptionsAddEllipsisMask(builder, ellipsisMask): builder.PrependInt32Slot(2, ellipsisMask, 0)
def AddEllipsisMask(builder, ellipsisMask):
    return StridedSliceOptionsAddEllipsisMask(builder, ellipsisMask)
def StridedSliceOptionsAddNewAxisMask(builder, newAxisMask): builder.PrependInt32Slot(3, newAxisMask, 0)
def AddNewAxisMask(builder, newAxisMask):
    return StridedSliceOptionsAddNewAxisMask(builder, newAxisMask)
def StridedSliceOptionsAddShrinkAxisMask(builder, shrinkAxisMask): builder.PrependInt32Slot(4, shrinkAxisMask, 0)
def AddShrinkAxisMask(builder, shrinkAxisMask):
    return StridedSliceOptionsAddShrinkAxisMask(builder, shrinkAxisMask)
def StridedSliceOptionsAddOffset(builder, offset): builder.PrependBoolSlot(5, offset, 0)
def AddOffset(builder, offset):
    return StridedSliceOptionsAddOffset(builder, offset)
def StridedSliceOptionsEnd(builder): return builder.EndObject()
def End(builder):
    return StridedSliceOptionsEnd(builder)