#
# Autogenerated by Thrift for thrift/compiler/test/fixtures/complex-union/src/module.thrift
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#  @generated
#
cimport cython as __cython
from cpython.object cimport PyTypeObject
from libcpp.memory cimport shared_ptr, make_shared, unique_ptr
from libcpp.optional cimport optional as __optional
from libcpp.string cimport string
from libcpp cimport bool as cbool
from libcpp.iterator cimport inserter as cinserter
from libcpp.utility cimport move as cmove
from cpython cimport bool as pbool
from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address
import thrift.py3.types
from thrift.py3.types import _IsSet as _fbthrift_IsSet
from thrift.py3.types cimport make_unique
cimport thrift.py3.types
cimport thrift.py3.exceptions
cimport thrift.python.exceptions
from thrift.python.types import EnumMeta as __EnumMeta
from thrift.python.std_libcpp cimport sv_to_str as __sv_to_str, string_view as __cstring_view
from thrift.python.types cimport(
    BadEnum as __BadEnum,
)
from thrift.py3.types cimport (
    cSetOp as __cSetOp,
    richcmp as __richcmp,
    set_op as __set_op,
    setcmp as __setcmp,
    init_unicode_from_cpp as __init_unicode_from_cpp,
    set_iter as __set_iter,
    map_iter as __map_iter,
    map_contains as __map_contains,
    map_getitem as __map_getitem,
    reference_shared_ptr as __reference_shared_ptr,
    get_field_name_by_index as __get_field_name_by_index,
    reset_field as __reset_field,
    translate_cpp_enum_to_python,
    const_pointer_cast,
    make_const_shared,
    constant_shared_ptr,
)
cimport thrift.py3.serializer as serializer
from thrift.python.protocol cimport Protocol as __Protocol
import folly.iobuf as _fbthrift_iobuf
from folly.optional cimport cOptional
from folly.memory cimport to_shared_ptr as __to_shared_ptr
from folly.range cimport Range as __cRange

import sys
from collections.abc import Sequence, Set, Mapping, Iterable
import weakref as __weakref
import builtins as _builtins
import importlib

from module.types_impl_FBTHRIFT_ONLY_DO_NOT_USE import (
    __ComplexUnionType,
    __ListUnionType,
    __DataUnionType,
    __ValUnionType,
    __VirtualComplexUnionType,
    __NonCopyableUnionType,
)

from module.containers_FBTHRIFT_ONLY_DO_NOT_USE import (
    List__i64,
    List__string,
)


cdef object get_types_reflection():
    import importlib
    return importlib.import_module(
        "module.types_reflection"
    )



@__cython.auto_pickle(False)
cdef class ComplexUnion(thrift.py3.types.Union):
    Type = __ComplexUnionType

    def __init__(
        self, *,
        intValue=None,
        str stringValue=None,
        intListValue=None,
        stringListValue=None,
        typedefValue=None,
        str stringRef=None
    ):
        if intValue is not None:
            if not isinstance(intValue, int):
                raise TypeError(f'intValue is not a { int !r}.')
            intValue = <cint64_t> intValue

        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = __to_shared_ptr(cmove(ComplexUnion._make_instance(
          NULL,
          intValue,
          stringValue,
          intListValue,
          stringListValue,
          typedefValue,
          stringRef,
        )))
        self._load_cache()

    @staticmethod
    def fromValue(value):
        if value is None:
            return ComplexUnion()
        if isinstance(value, int):
            if not isinstance(value, pbool):
                try:
                    <cint64_t> value
                    return ComplexUnion(intValue=value)
                except OverflowError:
                    pass
        if isinstance(value, str):
            return ComplexUnion(stringValue=value)
        if isinstance(value, List__i64):
            return ComplexUnion(intListValue=value)
        if isinstance(value, List__string):
            return ComplexUnion(stringListValue=value)
        if isinstance(value, Map__i16_string):
            return ComplexUnion(typedefValue=value)
        if isinstance(value, str):
            return ComplexUnion(stringRef=value)
        raise ValueError(f"Unable to derive correct union field for value: {value}")

    @staticmethod
    cdef unique_ptr[_module_cbindings.cComplexUnion] _make_instance(
        _module_cbindings.cComplexUnion* base_instance,
        object intValue,
        str stringValue,
        object intListValue,
        object stringListValue,
        object typedefValue,
        str stringRef
    ) except *:
        cdef unique_ptr[_module_cbindings.cComplexUnion] c_inst = make_unique[_module_cbindings.cComplexUnion]()
        cdef bint any_set = False
        if intValue is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_intValue(intValue)
            any_set = True
        if stringValue is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_stringValue(stringValue.encode('UTF-8'))
            any_set = True
        if intListValue is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_intListValue(List__i64__make_instance(intListValue))
            any_set = True
        if stringListValue is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_stringListValue(List__string__make_instance(stringListValue))
            any_set = True
        if typedefValue is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_typedefValue(<cmap[cint16_t,string]>deref(Map__i16_string(typedefValue)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE))
            any_set = True
        if stringRef is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_stringRef(string(deref((<str?>stringRef)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)))
            any_set = True
        # in C++ you don't have to call move(), but this doesn't translate
        # into a C++ return statement, so you do here
        return cmove(c_inst)

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[_module_cbindings.cComplexUnion] cpp_obj):
        __fbthrift_inst = <ComplexUnion>ComplexUnion.__new__(ComplexUnion)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(cpp_obj)
        __fbthrift_inst._load_cache()
        return __fbthrift_inst

    @property
    def intValue(self):
        if self.type.value != 1:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not intValue')
        return self.value

    @property
    def stringValue(self):
        if self.type.value != 5:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not stringValue')
        return self.value

    @property
    def intListValue(self):
        if self.type.value != 2:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not intListValue')
        return self.value

    @property
    def stringListValue(self):
        if self.type.value != 3:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not stringListValue')
        return self.value

    @property
    def typedefValue(self):
        if self.type.value != 9:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not typedefValue')
        return self.value

    @property
    def stringRef(self):
        if self.type.value != 14:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not stringRef')
        return self.value


    def __hash__(ComplexUnion self):
        return  super().__hash__()

    cdef _load_cache(ComplexUnion self):
        self.type = ComplexUnion.Type(<int>(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).getType()))
        cdef int type = self.type.value
        if type == 0:    # Empty
            self.value = None
        elif type == 1:
            self.value = deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_intValue()
        elif type == 5:
            self.value = bytes(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_stringValue()).decode('UTF-8')
        elif type == 2:
            self.value = List__i64__from_cpp(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_intListValue())
        elif type == 3:
            self.value = List__string__from_cpp(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_stringListValue())
        elif type == 9:
            self.value = Map__i16_string._create_FBTHRIFT_ONLY_DO_NOT_USE(make_shared[cmap[cint16_t,string]](deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_typedefValue()))
        elif type == 14:
            if not deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_stringRef():
                self.value = None
            else:
            
                self.value = str._create_FBTHRIFT_ONLY_DO_NOT_USE(__reference_shared_ptr(deref(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_stringRef()), self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE))

    def __copy__(ComplexUnion self):
        cdef shared_ptr[_module_cbindings.cComplexUnion] cpp_obj = make_shared[_module_cbindings.cComplexUnion](
            deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        )
        return ComplexUnion._create_FBTHRIFT_ONLY_DO_NOT_USE(cmove(cpp_obj))

    def __richcmp__(self, other, int op):
        r = self._fbthrift_cmp_sametype(other, op)
        return __richcmp[_module_cbindings.cComplexUnion](
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            (<ComplexUnion>other)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            op,
        ) if r is None else r

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__ComplexUnion()

    @staticmethod
    def __get_metadata__():
        cdef __fbthrift_cThriftMetadata meta
        _module_cbindings.StructMetadata[_module_cbindings.cComplexUnion].gen(meta)
        return __MetadataBox.box(cmove(meta))

    @staticmethod
    def __get_thrift_name__():
        return "module.ComplexUnion"

    @classmethod
    def _fbthrift_get_field_name_by_index(cls, idx):
        return __sv_to_str(__get_field_name_by_index[_module_cbindings.cComplexUnion](idx))

    @classmethod
    def _fbthrift_get_struct_size(cls):
        return 6

    cdef _fbthrift_iobuf.IOBuf _fbthrift_serialize(ComplexUnion self, __Protocol proto):
        cdef unique_ptr[_fbthrift_iobuf.cIOBuf] data
        with nogil:
            data = cmove(serializer.cserialize[_module_cbindings.cComplexUnion](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto))
        return _fbthrift_iobuf.from_unique_ptr(cmove(data))

    cdef cuint32_t _fbthrift_deserialize(ComplexUnion self, const _fbthrift_iobuf.cIOBuf* buf, __Protocol proto) except? 0:
        cdef cuint32_t needed
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cComplexUnion]()
        with nogil:
            needed = serializer.cdeserialize[_module_cbindings.cComplexUnion](buf, self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto)
        # force a cache reload since the underlying data's changed
        self._load_cache()
        return needed


    def _to_python(self):
        import importlib
        import thrift.python.converter
        python_types = importlib.import_module(
            "module.thrift_types"
        )
        return thrift.python.converter.to_python_struct(python_types.ComplexUnion, self)

    def _to_py3(self):
        return self

    def _to_py_deprecated(self):
        import importlib
        import thrift.util.converter
        py_deprecated_types = importlib.import_module("module.ttypes")
        return thrift.util.converter.to_py_struct(py_deprecated_types.ComplexUnion, self)



@__cython.auto_pickle(False)
cdef class ListUnion(thrift.py3.types.Union):
    Type = __ListUnionType

    def __init__(
        self, *,
        intListValue=None,
        stringListValue=None
    ):
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = __to_shared_ptr(cmove(ListUnion._make_instance(
          NULL,
          intListValue,
          stringListValue,
        )))
        self._load_cache()

    @staticmethod
    def fromValue(value):
        if value is None:
            return ListUnion()
        if isinstance(value, List__i64):
            return ListUnion(intListValue=value)
        if isinstance(value, List__string):
            return ListUnion(stringListValue=value)
        raise ValueError(f"Unable to derive correct union field for value: {value}")

    @staticmethod
    cdef unique_ptr[_module_cbindings.cListUnion] _make_instance(
        _module_cbindings.cListUnion* base_instance,
        object intListValue,
        object stringListValue
    ) except *:
        cdef unique_ptr[_module_cbindings.cListUnion] c_inst = make_unique[_module_cbindings.cListUnion]()
        cdef bint any_set = False
        if intListValue is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_intListValue(List__i64__make_instance(intListValue))
            any_set = True
        if stringListValue is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_stringListValue(List__string__make_instance(stringListValue))
            any_set = True
        # in C++ you don't have to call move(), but this doesn't translate
        # into a C++ return statement, so you do here
        return cmove(c_inst)

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[_module_cbindings.cListUnion] cpp_obj):
        __fbthrift_inst = <ListUnion>ListUnion.__new__(ListUnion)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(cpp_obj)
        __fbthrift_inst._load_cache()
        return __fbthrift_inst

    @property
    def intListValue(self):
        if self.type.value != 2:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not intListValue')
        return self.value

    @property
    def stringListValue(self):
        if self.type.value != 3:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not stringListValue')
        return self.value


    def __hash__(ListUnion self):
        return  super().__hash__()

    cdef _load_cache(ListUnion self):
        self.type = ListUnion.Type(<int>(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).getType()))
        cdef int type = self.type.value
        if type == 0:    # Empty
            self.value = None
        elif type == 2:
            self.value = List__i64__from_cpp(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_intListValue())
        elif type == 3:
            self.value = List__string__from_cpp(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_stringListValue())

    def __copy__(ListUnion self):
        cdef shared_ptr[_module_cbindings.cListUnion] cpp_obj = make_shared[_module_cbindings.cListUnion](
            deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        )
        return ListUnion._create_FBTHRIFT_ONLY_DO_NOT_USE(cmove(cpp_obj))

    def __richcmp__(self, other, int op):
        r = self._fbthrift_cmp_sametype(other, op)
        return __richcmp[_module_cbindings.cListUnion](
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            (<ListUnion>other)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            op,
        ) if r is None else r

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__ListUnion()

    @staticmethod
    def __get_metadata__():
        cdef __fbthrift_cThriftMetadata meta
        _module_cbindings.StructMetadata[_module_cbindings.cListUnion].gen(meta)
        return __MetadataBox.box(cmove(meta))

    @staticmethod
    def __get_thrift_name__():
        return "module.ListUnion"

    @classmethod
    def _fbthrift_get_field_name_by_index(cls, idx):
        return __sv_to_str(__get_field_name_by_index[_module_cbindings.cListUnion](idx))

    @classmethod
    def _fbthrift_get_struct_size(cls):
        return 2

    cdef _fbthrift_iobuf.IOBuf _fbthrift_serialize(ListUnion self, __Protocol proto):
        cdef unique_ptr[_fbthrift_iobuf.cIOBuf] data
        with nogil:
            data = cmove(serializer.cserialize[_module_cbindings.cListUnion](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto))
        return _fbthrift_iobuf.from_unique_ptr(cmove(data))

    cdef cuint32_t _fbthrift_deserialize(ListUnion self, const _fbthrift_iobuf.cIOBuf* buf, __Protocol proto) except? 0:
        cdef cuint32_t needed
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cListUnion]()
        with nogil:
            needed = serializer.cdeserialize[_module_cbindings.cListUnion](buf, self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto)
        # force a cache reload since the underlying data's changed
        self._load_cache()
        return needed


    def _to_python(self):
        import importlib
        import thrift.python.converter
        python_types = importlib.import_module(
            "module.thrift_types"
        )
        return thrift.python.converter.to_python_struct(python_types.ListUnion, self)

    def _to_py3(self):
        return self

    def _to_py_deprecated(self):
        import importlib
        import thrift.util.converter
        py_deprecated_types = importlib.import_module("module.ttypes")
        return thrift.util.converter.to_py_struct(py_deprecated_types.ListUnion, self)



@__cython.auto_pickle(False)
cdef class DataUnion(thrift.py3.types.Union):
    Type = __DataUnionType

    def __init__(
        self, *,
        bytes binaryData=None,
        str stringData=None
    ):
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = __to_shared_ptr(cmove(DataUnion._make_instance(
          NULL,
          binaryData,
          stringData,
        )))
        self._load_cache()

    @staticmethod
    def fromValue(value):
        if value is None:
            return DataUnion()
        if isinstance(value, bytes):
            return DataUnion(binaryData=value)
        if isinstance(value, str):
            return DataUnion(stringData=value)
        raise ValueError(f"Unable to derive correct union field for value: {value}")

    @staticmethod
    cdef unique_ptr[_module_cbindings.cDataUnion] _make_instance(
        _module_cbindings.cDataUnion* base_instance,
        bytes binaryData,
        str stringData
    ) except *:
        cdef unique_ptr[_module_cbindings.cDataUnion] c_inst = make_unique[_module_cbindings.cDataUnion]()
        cdef bint any_set = False
        if binaryData is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_binaryData(binaryData)
            any_set = True
        if stringData is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_stringData(stringData.encode('UTF-8'))
            any_set = True
        # in C++ you don't have to call move(), but this doesn't translate
        # into a C++ return statement, so you do here
        return cmove(c_inst)

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[_module_cbindings.cDataUnion] cpp_obj):
        __fbthrift_inst = <DataUnion>DataUnion.__new__(DataUnion)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(cpp_obj)
        __fbthrift_inst._load_cache()
        return __fbthrift_inst

    @property
    def binaryData(self):
        if self.type.value != 1:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not binaryData')
        return self.value

    @property
    def stringData(self):
        if self.type.value != 2:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not stringData')
        return self.value


    def __hash__(DataUnion self):
        return  super().__hash__()

    cdef _load_cache(DataUnion self):
        self.type = DataUnion.Type(<int>(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).getType()))
        cdef int type = self.type.value
        if type == 0:    # Empty
            self.value = None
        elif type == 1:
            self.value = deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_binaryData()
        elif type == 2:
            self.value = bytes(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_stringData()).decode('UTF-8')

    def __copy__(DataUnion self):
        cdef shared_ptr[_module_cbindings.cDataUnion] cpp_obj = make_shared[_module_cbindings.cDataUnion](
            deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        )
        return DataUnion._create_FBTHRIFT_ONLY_DO_NOT_USE(cmove(cpp_obj))

    def __richcmp__(self, other, int op):
        r = self._fbthrift_cmp_sametype(other, op)
        return __richcmp[_module_cbindings.cDataUnion](
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            (<DataUnion>other)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            op,
        ) if r is None else r

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__DataUnion()

    @staticmethod
    def __get_metadata__():
        cdef __fbthrift_cThriftMetadata meta
        _module_cbindings.StructMetadata[_module_cbindings.cDataUnion].gen(meta)
        return __MetadataBox.box(cmove(meta))

    @staticmethod
    def __get_thrift_name__():
        return "module.DataUnion"

    @classmethod
    def _fbthrift_get_field_name_by_index(cls, idx):
        return __sv_to_str(__get_field_name_by_index[_module_cbindings.cDataUnion](idx))

    @classmethod
    def _fbthrift_get_struct_size(cls):
        return 2

    cdef _fbthrift_iobuf.IOBuf _fbthrift_serialize(DataUnion self, __Protocol proto):
        cdef unique_ptr[_fbthrift_iobuf.cIOBuf] data
        with nogil:
            data = cmove(serializer.cserialize[_module_cbindings.cDataUnion](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto))
        return _fbthrift_iobuf.from_unique_ptr(cmove(data))

    cdef cuint32_t _fbthrift_deserialize(DataUnion self, const _fbthrift_iobuf.cIOBuf* buf, __Protocol proto) except? 0:
        cdef cuint32_t needed
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cDataUnion]()
        with nogil:
            needed = serializer.cdeserialize[_module_cbindings.cDataUnion](buf, self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto)
        # force a cache reload since the underlying data's changed
        self._load_cache()
        return needed


    def _to_python(self):
        import importlib
        import thrift.python.converter
        python_types = importlib.import_module(
            "module.thrift_types"
        )
        return thrift.python.converter.to_python_struct(python_types.DataUnion, self)

    def _to_py3(self):
        return self

    def _to_py_deprecated(self):
        import importlib
        import thrift.util.converter
        py_deprecated_types = importlib.import_module("module.ttypes")
        return thrift.util.converter.to_py_struct(py_deprecated_types.DataUnion, self)

@__cython.auto_pickle(False)
cdef class Val(thrift.py3.types.Struct):
    def __init__(Val self, **kwargs):
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cVal]()
        self._fields_setter = _fbthrift_types_fields.__Val_FieldsSetter._fbthrift_create(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get())
        super().__init__(**kwargs)

    def __call__(Val self, **kwargs):
        if not kwargs:
            return self
        cdef Val __fbthrift_inst = Val.__new__(Val)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cVal](deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE))
        __fbthrift_inst._fields_setter = _fbthrift_types_fields.__Val_FieldsSetter._fbthrift_create(__fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get())
        for __fbthrift_name, _fbthrift_value in kwargs.items():
            __fbthrift_inst._fbthrift_set_field(__fbthrift_name, _fbthrift_value)
        return __fbthrift_inst

    cdef void _fbthrift_set_field(self, str name, object value) except *:
        self._fields_setter.set_field(name.encode("utf-8"), value)

    cdef object _fbthrift_isset(self):
        return _fbthrift_IsSet("Val", {
          "strVal": deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).strVal_ref().has_value(),
          "intVal": deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).intVal_ref().has_value(),
          "typedefValue": deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).typedefValue_ref().has_value(),
        })

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[_module_cbindings.cVal] cpp_obj):
        __fbthrift_inst = <Val>Val.__new__(Val)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(cpp_obj)
        return __fbthrift_inst

    cdef inline strVal_impl(self):
        return (<bytes>deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).strVal_ref().value()).decode('UTF-8')

    @property
    def strVal(self):
        return self.strVal_impl()

    cdef inline intVal_impl(self):
        return deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).intVal_ref().value()

    @property
    def intVal(self):
        return self.intVal_impl()

    cdef inline typedefValue_impl(self):
        if self.__fbthrift_cached_typedefValue is None:
            self.__fbthrift_cached_typedefValue = Map__i16_string._create_FBTHRIFT_ONLY_DO_NOT_USE(__reference_shared_ptr(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).typedefValue_ref().ref(), self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE))
        return self.__fbthrift_cached_typedefValue

    @property
    def typedefValue(self):
        return self.typedefValue_impl()


    def __hash__(Val self):
        return super().__hash__()

    def __repr__(Val self):
        return super().__repr__()

    def __str__(Val self):
        return super().__str__()


    def __copy__(Val self):
        cdef shared_ptr[_module_cbindings.cVal] cpp_obj = make_shared[_module_cbindings.cVal](
            deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        )
        return Val._create_FBTHRIFT_ONLY_DO_NOT_USE(cmove(cpp_obj))

    def __richcmp__(self, other, int op):
        r = self._fbthrift_cmp_sametype(other, op)
        return __richcmp[_module_cbindings.cVal](
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            (<Val>other)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            op,
        ) if r is None else r

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__Val()

    @staticmethod
    def __get_metadata__():
        cdef __fbthrift_cThriftMetadata meta
        _module_cbindings.StructMetadata[_module_cbindings.cVal].gen(meta)
        return __MetadataBox.box(cmove(meta))

    @staticmethod
    def __get_thrift_name__():
        return "module.Val"

    @classmethod
    def _fbthrift_get_field_name_by_index(cls, idx):
        return __sv_to_str(__get_field_name_by_index[_module_cbindings.cVal](idx))

    @classmethod
    def _fbthrift_get_struct_size(cls):
        return 3

    cdef _fbthrift_iobuf.IOBuf _fbthrift_serialize(Val self, __Protocol proto):
        cdef unique_ptr[_fbthrift_iobuf.cIOBuf] data
        with nogil:
            data = cmove(serializer.cserialize[_module_cbindings.cVal](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto))
        return _fbthrift_iobuf.from_unique_ptr(cmove(data))

    cdef cuint32_t _fbthrift_deserialize(Val self, const _fbthrift_iobuf.cIOBuf* buf, __Protocol proto) except? 0:
        cdef cuint32_t needed
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cVal]()
        with nogil:
            needed = serializer.cdeserialize[_module_cbindings.cVal](buf, self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto)
        return needed


    def _to_python(self):
        import importlib
        import thrift.python.converter
        python_types = importlib.import_module(
            "module.thrift_types"
        )
        return thrift.python.converter.to_python_struct(python_types.Val, self)

    def _to_py3(self):
        return self

    def _to_py_deprecated(self):
        import importlib
        import thrift.util.converter
        py_deprecated_types = importlib.import_module("module.ttypes")
        return thrift.util.converter.to_py_struct(py_deprecated_types.Val, self)



@__cython.auto_pickle(False)
cdef class ValUnion(thrift.py3.types.Union):
    Type = __ValUnionType

    def __init__(
        self, *,
        Val v1=None,
        Val v2=None
    ):
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = __to_shared_ptr(cmove(ValUnion._make_instance(
          NULL,
          v1,
          v2,
        )))
        self._load_cache()

    @staticmethod
    def fromValue(value):
        if value is None:
            return ValUnion()
        if isinstance(value, Val):
            return ValUnion(v1=value)
        if isinstance(value, Val):
            return ValUnion(v2=value)
        raise ValueError(f"Unable to derive correct union field for value: {value}")

    @staticmethod
    cdef unique_ptr[_module_cbindings.cValUnion] _make_instance(
        _module_cbindings.cValUnion* base_instance,
        Val v1,
        Val v2
    ) except *:
        cdef unique_ptr[_module_cbindings.cValUnion] c_inst = make_unique[_module_cbindings.cValUnion]()
        cdef bint any_set = False
        if v1 is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_v1(deref((<Val?> v1)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE))
            any_set = True
        if v2 is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_v2(deref((<Val?> v2)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE))
            any_set = True
        # in C++ you don't have to call move(), but this doesn't translate
        # into a C++ return statement, so you do here
        return cmove(c_inst)

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[_module_cbindings.cValUnion] cpp_obj):
        __fbthrift_inst = <ValUnion>ValUnion.__new__(ValUnion)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(cpp_obj)
        __fbthrift_inst._load_cache()
        return __fbthrift_inst

    @property
    def v1(self):
        if self.type.value != 1:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not v1')
        return self.value

    @property
    def v2(self):
        if self.type.value != 2:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not v2')
        return self.value


    def __hash__(ValUnion self):
        return  super().__hash__()

    cdef _load_cache(ValUnion self):
        self.type = ValUnion.Type(<int>(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).getType()))
        cdef int type = self.type.value
        if type == 0:    # Empty
            self.value = None
        elif type == 1:
            self.value = Val._create_FBTHRIFT_ONLY_DO_NOT_USE(make_shared[_module_cbindings.cVal](deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_v1()))
        elif type == 2:
            self.value = Val._create_FBTHRIFT_ONLY_DO_NOT_USE(make_shared[_module_cbindings.cVal](deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_v2()))

    def __copy__(ValUnion self):
        cdef shared_ptr[_module_cbindings.cValUnion] cpp_obj = make_shared[_module_cbindings.cValUnion](
            deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        )
        return ValUnion._create_FBTHRIFT_ONLY_DO_NOT_USE(cmove(cpp_obj))

    def __richcmp__(self, other, int op):
        r = self._fbthrift_cmp_sametype(other, op)
        return __richcmp[_module_cbindings.cValUnion](
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            (<ValUnion>other)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            op,
        ) if r is None else r

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__ValUnion()

    @staticmethod
    def __get_metadata__():
        cdef __fbthrift_cThriftMetadata meta
        _module_cbindings.StructMetadata[_module_cbindings.cValUnion].gen(meta)
        return __MetadataBox.box(cmove(meta))

    @staticmethod
    def __get_thrift_name__():
        return "module.ValUnion"

    @classmethod
    def _fbthrift_get_field_name_by_index(cls, idx):
        return __sv_to_str(__get_field_name_by_index[_module_cbindings.cValUnion](idx))

    @classmethod
    def _fbthrift_get_struct_size(cls):
        return 2

    cdef _fbthrift_iobuf.IOBuf _fbthrift_serialize(ValUnion self, __Protocol proto):
        cdef unique_ptr[_fbthrift_iobuf.cIOBuf] data
        with nogil:
            data = cmove(serializer.cserialize[_module_cbindings.cValUnion](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto))
        return _fbthrift_iobuf.from_unique_ptr(cmove(data))

    cdef cuint32_t _fbthrift_deserialize(ValUnion self, const _fbthrift_iobuf.cIOBuf* buf, __Protocol proto) except? 0:
        cdef cuint32_t needed
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cValUnion]()
        with nogil:
            needed = serializer.cdeserialize[_module_cbindings.cValUnion](buf, self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto)
        # force a cache reload since the underlying data's changed
        self._load_cache()
        return needed


    def _to_python(self):
        import importlib
        import thrift.python.converter
        python_types = importlib.import_module(
            "module.thrift_types"
        )
        return thrift.python.converter.to_python_struct(python_types.ValUnion, self)

    def _to_py3(self):
        return self

    def _to_py_deprecated(self):
        import importlib
        import thrift.util.converter
        py_deprecated_types = importlib.import_module("module.ttypes")
        return thrift.util.converter.to_py_struct(py_deprecated_types.ValUnion, self)



@__cython.auto_pickle(False)
cdef class VirtualComplexUnion(thrift.py3.types.Union):
    Type = __VirtualComplexUnionType

    def __init__(
        self, *,
        str thingOne=None,
        str thingTwo=None
    ):
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = __to_shared_ptr(cmove(VirtualComplexUnion._make_instance(
          NULL,
          thingOne,
          thingTwo,
        )))
        self._load_cache()

    @staticmethod
    def fromValue(value):
        if value is None:
            return VirtualComplexUnion()
        if isinstance(value, str):
            return VirtualComplexUnion(thingOne=value)
        if isinstance(value, str):
            return VirtualComplexUnion(thingTwo=value)
        raise ValueError(f"Unable to derive correct union field for value: {value}")

    @staticmethod
    cdef unique_ptr[_module_cbindings.cVirtualComplexUnion] _make_instance(
        _module_cbindings.cVirtualComplexUnion* base_instance,
        str thingOne,
        str thingTwo
    ) except *:
        cdef unique_ptr[_module_cbindings.cVirtualComplexUnion] c_inst = make_unique[_module_cbindings.cVirtualComplexUnion]()
        cdef bint any_set = False
        if thingOne is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_thingOne(thingOne.encode('UTF-8'))
            any_set = True
        if thingTwo is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_thingTwo(thingTwo.encode('UTF-8'))
            any_set = True
        # in C++ you don't have to call move(), but this doesn't translate
        # into a C++ return statement, so you do here
        return cmove(c_inst)

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[_module_cbindings.cVirtualComplexUnion] cpp_obj):
        __fbthrift_inst = <VirtualComplexUnion>VirtualComplexUnion.__new__(VirtualComplexUnion)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(cpp_obj)
        __fbthrift_inst._load_cache()
        return __fbthrift_inst

    @property
    def thingOne(self):
        if self.type.value != 1:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not thingOne')
        return self.value

    @property
    def thingTwo(self):
        if self.type.value != 2:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not thingTwo')
        return self.value


    def __hash__(VirtualComplexUnion self):
        return  super().__hash__()

    cdef _load_cache(VirtualComplexUnion self):
        self.type = VirtualComplexUnion.Type(<int>(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).getType()))
        cdef int type = self.type.value
        if type == 0:    # Empty
            self.value = None
        elif type == 1:
            self.value = bytes(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_thingOne()).decode('UTF-8')
        elif type == 2:
            self.value = bytes(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_thingTwo()).decode('UTF-8')

    def __copy__(VirtualComplexUnion self):
        cdef shared_ptr[_module_cbindings.cVirtualComplexUnion] cpp_obj = make_shared[_module_cbindings.cVirtualComplexUnion](
            deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        )
        return VirtualComplexUnion._create_FBTHRIFT_ONLY_DO_NOT_USE(cmove(cpp_obj))

    def __richcmp__(self, other, int op):
        r = self._fbthrift_cmp_sametype(other, op)
        return __richcmp[_module_cbindings.cVirtualComplexUnion](
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            (<VirtualComplexUnion>other)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            op,
        ) if r is None else r

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__VirtualComplexUnion()

    @staticmethod
    def __get_metadata__():
        cdef __fbthrift_cThriftMetadata meta
        _module_cbindings.StructMetadata[_module_cbindings.cVirtualComplexUnion].gen(meta)
        return __MetadataBox.box(cmove(meta))

    @staticmethod
    def __get_thrift_name__():
        return "module.VirtualComplexUnion"

    @classmethod
    def _fbthrift_get_field_name_by_index(cls, idx):
        return __sv_to_str(__get_field_name_by_index[_module_cbindings.cVirtualComplexUnion](idx))

    @classmethod
    def _fbthrift_get_struct_size(cls):
        return 2

    cdef _fbthrift_iobuf.IOBuf _fbthrift_serialize(VirtualComplexUnion self, __Protocol proto):
        cdef unique_ptr[_fbthrift_iobuf.cIOBuf] data
        with nogil:
            data = cmove(serializer.cserialize[_module_cbindings.cVirtualComplexUnion](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto))
        return _fbthrift_iobuf.from_unique_ptr(cmove(data))

    cdef cuint32_t _fbthrift_deserialize(VirtualComplexUnion self, const _fbthrift_iobuf.cIOBuf* buf, __Protocol proto) except? 0:
        cdef cuint32_t needed
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cVirtualComplexUnion]()
        with nogil:
            needed = serializer.cdeserialize[_module_cbindings.cVirtualComplexUnion](buf, self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto)
        # force a cache reload since the underlying data's changed
        self._load_cache()
        return needed


    def _to_python(self):
        import importlib
        import thrift.python.converter
        python_types = importlib.import_module(
            "module.thrift_types"
        )
        return thrift.python.converter.to_python_struct(python_types.VirtualComplexUnion, self)

    def _to_py3(self):
        return self

    def _to_py_deprecated(self):
        import importlib
        import thrift.util.converter
        py_deprecated_types = importlib.import_module("module.ttypes")
        return thrift.util.converter.to_py_struct(py_deprecated_types.VirtualComplexUnion, self)

@__cython.auto_pickle(False)
cdef class NonCopyableStruct(thrift.py3.types.Struct):
    def __init__(NonCopyableStruct self, **kwargs):
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cNonCopyableStruct]()
        self._fields_setter = _fbthrift_types_fields.__NonCopyableStruct_FieldsSetter._fbthrift_create(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get())
        super().__init__(**kwargs)

    cdef void _fbthrift_set_field(self, str name, object value) except *:
        self._fields_setter.set_field(name.encode("utf-8"), value)

    cdef object _fbthrift_isset(self):
        return _fbthrift_IsSet("NonCopyableStruct", {
          "num": deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).num_ref().has_value(),
        })

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[_module_cbindings.cNonCopyableStruct] cpp_obj):
        __fbthrift_inst = <NonCopyableStruct>NonCopyableStruct.__new__(NonCopyableStruct)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(cpp_obj)
        return __fbthrift_inst

    cdef inline num_impl(self):
        return deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).num_ref().value()

    @property
    def num(self):
        return self.num_impl()


    def __hash__(NonCopyableStruct self):
        return super().__hash__()

    def __repr__(NonCopyableStruct self):
        return super().__repr__()

    def __str__(NonCopyableStruct self):
        return super().__str__()


    def __copy__(NonCopyableStruct self):
        raise TypeError("NonCopyableStruct is noncopyable")

    def __richcmp__(self, other, int op):
        r = self._fbthrift_cmp_sametype(other, op)
        return __richcmp[_module_cbindings.cNonCopyableStruct](
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            (<NonCopyableStruct>other)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            op,
        ) if r is None else r

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__NonCopyableStruct()

    @staticmethod
    def __get_metadata__():
        cdef __fbthrift_cThriftMetadata meta
        _module_cbindings.StructMetadata[_module_cbindings.cNonCopyableStruct].gen(meta)
        return __MetadataBox.box(cmove(meta))

    @staticmethod
    def __get_thrift_name__():
        return "module.NonCopyableStruct"

    @classmethod
    def _fbthrift_get_field_name_by_index(cls, idx):
        return __sv_to_str(__get_field_name_by_index[_module_cbindings.cNonCopyableStruct](idx))

    @classmethod
    def _fbthrift_get_struct_size(cls):
        return 1

    cdef _fbthrift_iobuf.IOBuf _fbthrift_serialize(NonCopyableStruct self, __Protocol proto):
        cdef unique_ptr[_fbthrift_iobuf.cIOBuf] data
        with nogil:
            data = cmove(serializer.cserialize[_module_cbindings.cNonCopyableStruct](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto))
        return _fbthrift_iobuf.from_unique_ptr(cmove(data))

    cdef cuint32_t _fbthrift_deserialize(NonCopyableStruct self, const _fbthrift_iobuf.cIOBuf* buf, __Protocol proto) except? 0:
        cdef cuint32_t needed
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cNonCopyableStruct]()
        with nogil:
            needed = serializer.cdeserialize[_module_cbindings.cNonCopyableStruct](buf, self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto)
        return needed


    def _to_python(self):
        import importlib
        import thrift.python.converter
        python_types = importlib.import_module(
            "module.thrift_types"
        )
        return thrift.python.converter.to_python_struct(python_types.NonCopyableStruct, self)

    def _to_py3(self):
        return self

    def _to_py_deprecated(self):
        import importlib
        import thrift.util.converter
        py_deprecated_types = importlib.import_module("module.ttypes")
        return thrift.util.converter.to_py_struct(py_deprecated_types.NonCopyableStruct, self)



@__cython.auto_pickle(False)
cdef class NonCopyableUnion(thrift.py3.types.Union):
    Type = __NonCopyableUnionType

    def __init__(
        self, *,
        NonCopyableStruct s=None
    ):
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = __to_shared_ptr(cmove(NonCopyableUnion._make_instance(
          NULL,
          s,
        )))
        self._load_cache()

    @staticmethod
    def fromValue(value):
        if value is None:
            return NonCopyableUnion()
        if isinstance(value, NonCopyableStruct):
            return NonCopyableUnion(s=value)
        raise ValueError(f"Unable to derive correct union field for value: {value}")

    @staticmethod
    cdef unique_ptr[_module_cbindings.cNonCopyableUnion] _make_instance(
        _module_cbindings.cNonCopyableUnion* base_instance,
        NonCopyableStruct s
    ) except *:
        cdef unique_ptr[_module_cbindings.cNonCopyableUnion] c_inst = make_unique[_module_cbindings.cNonCopyableUnion]()
        cdef bint any_set = False
        if s is not None:
            if any_set:
                raise TypeError("At most one field may be set when initializing a union")
            deref(c_inst).set_s(deref((<NonCopyableStruct?> s)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE))
            any_set = True
        # in C++ you don't have to call move(), but this doesn't translate
        # into a C++ return statement, so you do here
        return cmove(c_inst)

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[_module_cbindings.cNonCopyableUnion] cpp_obj):
        __fbthrift_inst = <NonCopyableUnion>NonCopyableUnion.__new__(NonCopyableUnion)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(cpp_obj)
        __fbthrift_inst._load_cache()
        return __fbthrift_inst

    @property
    def s(self):
        if self.type.value != 1:
            raise AttributeError(f'Union contains a value of type {self.type.name}, not s')
        return self.value


    def __hash__(NonCopyableUnion self):
        return  super().__hash__()

    cdef _load_cache(NonCopyableUnion self):
        self.type = NonCopyableUnion.Type(<int>(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).getType()))
        cdef int type = self.type.value
        if type == 0:    # Empty
            self.value = None
        elif type == 1:
            self.value = NonCopyableStruct._create_FBTHRIFT_ONLY_DO_NOT_USE(make_shared[_module_cbindings.cNonCopyableStruct](deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).get_s()))

    def __copy__(NonCopyableUnion self):
        raise TypeError("NonCopyableUnion is noncopyable")

    def __richcmp__(self, other, int op):
        r = self._fbthrift_cmp_sametype(other, op)
        return __richcmp[_module_cbindings.cNonCopyableUnion](
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            (<NonCopyableUnion>other)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE,
            op,
        ) if r is None else r

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__NonCopyableUnion()

    @staticmethod
    def __get_metadata__():
        cdef __fbthrift_cThriftMetadata meta
        _module_cbindings.StructMetadata[_module_cbindings.cNonCopyableUnion].gen(meta)
        return __MetadataBox.box(cmove(meta))

    @staticmethod
    def __get_thrift_name__():
        return "module.NonCopyableUnion"

    @classmethod
    def _fbthrift_get_field_name_by_index(cls, idx):
        return __sv_to_str(__get_field_name_by_index[_module_cbindings.cNonCopyableUnion](idx))

    @classmethod
    def _fbthrift_get_struct_size(cls):
        return 1

    cdef _fbthrift_iobuf.IOBuf _fbthrift_serialize(NonCopyableUnion self, __Protocol proto):
        cdef unique_ptr[_fbthrift_iobuf.cIOBuf] data
        with nogil:
            data = cmove(serializer.cserialize[_module_cbindings.cNonCopyableUnion](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto))
        return _fbthrift_iobuf.from_unique_ptr(cmove(data))

    cdef cuint32_t _fbthrift_deserialize(NonCopyableUnion self, const _fbthrift_iobuf.cIOBuf* buf, __Protocol proto) except? 0:
        cdef cuint32_t needed
        self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = make_shared[_module_cbindings.cNonCopyableUnion]()
        with nogil:
            needed = serializer.cdeserialize[_module_cbindings.cNonCopyableUnion](buf, self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE.get(), proto)
        # force a cache reload since the underlying data's changed
        self._load_cache()
        return needed


    def _to_python(self):
        import importlib
        import thrift.python.converter
        python_types = importlib.import_module(
            "module.thrift_types"
        )
        return thrift.python.converter.to_python_struct(python_types.NonCopyableUnion, self)

    def _to_py3(self):
        return self

    def _to_py_deprecated(self):
        import importlib
        import thrift.util.converter
        py_deprecated_types = importlib.import_module("module.ttypes")
        return thrift.util.converter.to_py_struct(py_deprecated_types.NonCopyableUnion, self)


cdef vector[cint64_t] List__i64__make_instance(object items) except *:
    cdef vector[cint64_t] c_inst
    if items is not None:
        for item in items:
            if not isinstance(item, int):
                raise TypeError(f"{item!r} is not of type int")
            item = <cint64_t> item
            c_inst.push_back(item)
    return cmove(c_inst)

cdef object List__i64__from_cpp(const vector[cint64_t]& c_vec) except *:
    cdef list py_list = []
    cdef int idx = 0
    for idx in range(c_vec.size()):
        py_list.append(c_vec[idx])
    return List__i64(py_list, thrift.py3.types._fbthrift_list_private_ctor)


cdef vector[string] List__string__make_instance(object items) except *:
    cdef vector[string] c_inst
    if items is not None:
        if isinstance(items, str):
            raise TypeError("If you really want to pass a string into a _typing.Sequence[str] field, explicitly convert it first.")
        for item in items:
            if not isinstance(item, str):
                raise TypeError(f"{item!r} is not of type str")
            c_inst.push_back(item.encode('UTF-8'))
    return cmove(c_inst)

cdef object List__string__from_cpp(const vector[string]& c_vec) except *:
    cdef list py_list = []
    cdef int idx = 0
    for idx in range(c_vec.size()):
        py_list.append(__init_unicode_from_cpp(c_vec[idx]))
    return List__string(py_list, thrift.py3.types._fbthrift_list_private_ctor)

@__cython.auto_pickle(False)
@__cython.final
cdef class Map__i16_string(thrift.py3.types.Map):
    def __init__(self, items=None):
        if isinstance(items, Map__i16_string):
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = (<Map__i16_string> items)._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE
        else:
            self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = Map__i16_string__make_instance(items)

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[cmap[cint16_t,string]] c_items):
        __fbthrift_inst = <Map__i16_string>Map__i16_string.__new__(Map__i16_string)
        __fbthrift_inst._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE = cmove(c_items)
        return __fbthrift_inst

    def __copy__(Map__i16_string self):
        cdef shared_ptr[cmap[cint16_t,string]] cpp_obj = make_shared[cmap[cint16_t,string]](
            deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        )
        return Map__i16_string._create_FBTHRIFT_ONLY_DO_NOT_USE(cmove(cpp_obj))

    def __len__(self):
        return deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).size()

    cdef _check_key_type(self, key):
        if not self or key is None:
            return
        if isinstance(key, int):
            return key

    def __getitem__(self, key):
        err = KeyError(f'{key}')
        key = self._check_key_type(key)
        if key is None:
            raise err
        cdef cint16_t ckey = key
        if not __map_contains(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE, ckey):
            raise err
        cdef string citem
        __map_getitem(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE, ckey, citem)
        return bytes(citem).decode('UTF-8')

    def __iter__(self):
        if not self:
            return
        cdef __map_iter[cmap[cint16_t,string]] itr = __map_iter[cmap[cint16_t,string]](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        cdef cint16_t citem = 0
        for i in range(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).size()):
            itr.genNextKey(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE, citem)
            yield citem

    def __contains__(self, key):
        key = self._check_key_type(key)
        if key is None:
            return False
        cdef cint16_t ckey = key
        return __map_contains(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE, ckey)

    def values(self):
        if not self:
            return
        cdef __map_iter[cmap[cint16_t,string]] itr = __map_iter[cmap[cint16_t,string]](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        cdef string citem
        for i in range(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).size()):
            itr.genNextValue(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE, citem)
            yield bytes(citem).decode('UTF-8')

    def items(self):
        if not self:
            return
        cdef __map_iter[cmap[cint16_t,string]] itr = __map_iter[cmap[cint16_t,string]](self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE)
        cdef cint16_t ckey = 0
        cdef string citem
        for i in range(deref(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE).size()):
            itr.genNextItem(self._cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE, ckey, citem)
            yield (ckey, bytes(citem).decode('UTF-8'))

    @staticmethod
    def __get_reflection__():
        return get_types_reflection().get_reflection__Map__i16_string()

Mapping.register(Map__i16_string)

cdef shared_ptr[cmap[cint16_t,string]] Map__i16_string__make_instance(object items) except *:
    cdef shared_ptr[cmap[cint16_t,string]] c_inst = make_shared[cmap[cint16_t,string]]()
    if items is not None:
        for key, item in items.items():
            if not isinstance(key, int):
                raise TypeError(f"{key!r} is not of type int")
            key = <cint16_t> key
            if not isinstance(item, str):
                raise TypeError(f"{item!r} is not of type str")

            deref(c_inst)[key] = item.encode('UTF-8')
    return cmove(c_inst)



containerTypedef = Map__i16_string
