# automatically generated by the FlatBuffers compiler, do not modify

# namespace: tosa

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

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

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

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

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

    # Version
    def _major(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

    # Version
    def _minor(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 50

    # Version
    def _patch(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

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

def VersionStart(builder): builder.StartObject(4)
def Start(builder):
    return VersionStart(builder)
def VersionAdd_major(builder, Major): builder.PrependInt32Slot(0, Major, 0)
def Add_major(builder, Major):
    return VersionAdd_major(builder, Major)
def VersionAdd_minor(builder, Minor): builder.PrependInt32Slot(1, Minor, 50)
def Add_minor(builder, Minor):
    return VersionAdd_minor(builder, Minor)
def VersionAdd_patch(builder, Patch): builder.PrependInt32Slot(2, Patch, 0)
def Add_patch(builder, Patch):
    return VersionAdd_patch(builder, Patch)
def VersionAdd_draft(builder, Draft): builder.PrependBoolSlot(3, Draft, 0)
def Add_draft(builder, Draft):
    return VersionAdd_draft(builder, Draft)
def VersionEnd(builder): return builder.EndObject()
def End(builder):
    return VersionEnd(builder)