from __future__ import annotations
import warnings
from typing import Tuple, Set, Dict, List, NamedTuple, Optional, TYPE_CHECKING
import krpc.limits
import krpc.schema
from krpc.schema import KRPC_pb2
from krpc.types import TypeBase, ClassBase, WrappedClass, DocEnum, StaticMethod
from krpc.event import Event
if TYPE_CHECKING:
    from krpc.services import Client
from krpc.services import krpc as _service_krpc


class DeprecatedEnum(DocEnum):
    """
    Deprecated. Use TestEnum instead.

    Deprecated enum documentation string.
    """
    value_a = 0, """
Deprecated enum ValueA documentation string.
"""
    value_b = 1, """
Deprecated enum ValueB documentation string.
"""


class TestEnum(DocEnum):
    """
    Enum documentation string.
    """
    value_a = 0, """
Enum ValueA documentation string.
"""
    value_b = 1, """
Enum ValueB documentation string.
"""
    value_c = 2, """
Enum ValueC documentation string.
"""


class DeprecatedStruct(NamedTuple):
    """
    Deprecated. Use TestStruct instead.

    Deprecated struct documentation string.
    """
    value: int
    """
    Deprecated struct Value documentation string.
    """
    old_value: int
    """
    Deprecated. Use DeprecatedStruct.value instead.

    Deprecated struct OldValue documentation string.
    """


class TestNestedNullableStruct(NamedTuple):
    """
    Nested nullable struct documentation string.
    """
    list_field: List[Optional[TestClass]]
    string_field: str


class TestStruct(NamedTuple):
    """
    Struct documentation string.
    """
    int_field: int
    """
    Struct IntField documentation string.
    """
    string_field: str
    enum_field: TestEnum
    list_field: List[int]


class TestNestedStruct(NamedTuple):
    """
    Nested struct documentation string.
    """
    struct_field: TestStruct
    object_field: TestClass
    string_field: str


class TestNullableStruct(NamedTuple):
    """
    Nullable struct documentation string.
    """
    int_field: int
    nullable_int_field: Optional[int]
    nullable_enum_field: Optional[TestEnum]
    nullable_string_field: Optional[str]
    nullable_object_field: Optional[TestClass]


class CustomException(RuntimeError):
    _service_name = 'TestService'
    _class_name = 'CustomException'


class DeprecatedException(RuntimeError):
    """
    Deprecated. Use CustomException instead.

    Deprecated exception documentation string.
    """
    _service_name = 'TestService'
    _class_name = 'DeprecatedException'


class DeprecatedClass(ClassBase):
    """
    Deprecated. Use TestClass instead.

    Deprecated class documentation string.
    """
    def deprecated_method(self) -> str:
        """
        Deprecated. Use TestClass.get_value instead.

        Deprecated method documentation string.
        """
        warnings.warn("TestService.DeprecatedClass.deprecated_method is deprecated: Use TestClass.get_value instead.", DeprecationWarning, stacklevel=2)
        return self._client._invoke(
            "TestService",
            "DeprecatedClass_DeprecatedMethod",
            [self, ],
            [self._client._types.class_type("TestService", "DeprecatedClass"), ],
            self._client._types.string_type
        )

    def _return_type_deprecated_method(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_deprecated_method(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "DeprecatedClass_DeprecatedMethod",
            [self, ],
            [self._client._types.class_type("TestService", "DeprecatedClass"), ],
            self._client._types.string_type
        )



class TestClass(ClassBase):
    """
    Class documentation string.
    """
    @property
    def int_property(self) -> int:
        """
        Property documentation string.
        """
        return self._client._invoke(
            "TestService",
            "TestClass_get_IntProperty",
            [self],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.sint32_type
        )

    @int_property.setter
    def int_property(self, value: int) -> None:
        return self._client._invoke(
            "TestService",
            "TestClass_set_IntProperty",
            [self, value],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.sint32_type],
            None
        )

    def _return_type_int_property(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_int_property(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TestClass_get_IntProperty",
            [self],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.sint32_type
        )

    @property
    def object_property(self) -> Optional[TestClass]:
        return self._client._invoke(
            "TestService",
            "TestClass_get_ObjectProperty",
            [self],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    @object_property.setter
    def object_property(self, value: Optional[TestClass]) -> None:
        return self._client._invoke(
            "TestService",
            "TestClass_set_ObjectProperty",
            [self, value],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.class_type("TestService", "TestClass")],
            None
        )

    def _return_type_object_property(self) -> TypeBase:
        return self._client._types.class_type("TestService", "TestClass")

    def _build_call_object_property(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TestClass_get_ObjectProperty",
            [self],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    @property
    def string_property_private_get(self) -> str:
        raise NotImplementedError

    @string_property_private_get.setter
    def string_property_private_get(self, value: str) -> None:
        return self._client._invoke(
            "TestService",
            "TestClass_set_StringPropertyPrivateGet",
            [self, value],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.string_type],
            None
        )

    @property
    def string_property_private_set(self) -> str:
        return self._client._invoke(
            "TestService",
            "TestClass_get_StringPropertyPrivateSet",
            [self],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.string_type
        )

    def _return_type_string_property_private_set(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_string_property_private_set(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TestClass_get_StringPropertyPrivateSet",
            [self],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.string_type
        )

    def echo_nullable_object(self, value: Optional[TestClass]) -> Optional[TestClass]:
        return self._client._invoke(
            "TestService",
            "TestClass_EchoNullableObject",
            [self, value],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    def _return_type_echo_nullable_object(self) -> TypeBase:
        return self._client._types.class_type("TestService", "TestClass")

    def _build_call_echo_nullable_object(self, value: Optional[TestClass]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TestClass_EchoNullableObject",
            [self, value],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    def float_to_string(self, x: float) -> str:
        return self._client._invoke(
            "TestService",
            "TestClass_FloatToString",
            [self, x],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.float_type],
            self._client._types.string_type
        )

    def _return_type_float_to_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_float_to_string(self, x: float) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TestClass_FloatToString",
            [self, x],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.float_type],
            self._client._types.string_type
        )

    def get_value(self) -> str:
        """
        Method documentation string.
        """
        return self._client._invoke(
            "TestService",
            "TestClass_GetValue",
            [self, ],
            [self._client._types.class_type("TestService", "TestClass"), ],
            self._client._types.string_type
        )

    def _return_type_get_value(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_get_value(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TestClass_GetValue",
            [self, ],
            [self._client._types.class_type("TestService", "TestClass"), ],
            self._client._types.string_type
        )

    def object_to_string(self, other: Optional[TestClass]) -> str:
        return self._client._invoke(
            "TestService",
            "TestClass_ObjectToString",
            [self, other],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.class_type("TestService", "TestClass")],
            self._client._types.string_type
        )

    def _return_type_object_to_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_object_to_string(self, other: Optional[TestClass]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TestClass_ObjectToString",
            [self, other],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.class_type("TestService", "TestClass")],
            self._client._types.string_type
        )

    def optional_arguments(self, x: str, y: str = 'foo', z: str = 'bar', obj: Optional[TestClass] = None) -> str:
        return self._client._invoke(
            "TestService",
            "TestClass_OptionalArguments",
            [self, x, y, z, obj],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.string_type, self._client._types.string_type, self._client._types.string_type, self._client._types.class_type("TestService", "TestClass")],
            self._client._types.string_type
        )

    def _return_type_optional_arguments(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_optional_arguments(self, x: str, y: str = 'foo', z: str = 'bar', obj: Optional[TestClass] = None) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TestClass_OptionalArguments",
            [self, x, y, z, obj],
            [self._client._types.class_type("TestService", "TestClass"), self._client._types.string_type, self._client._types.string_type, self._client._types.string_type, self._client._types.class_type("TestService", "TestClass")],
            self._client._types.string_type
        )

    @StaticMethod
    def static_method(cls, a: str = '', b: str = '') -> str:
        self = cls
        return cls._client._invoke(
            "TestService",
            "TestClass_static_StaticMethod",
            [a, b],
            [self._client._types.string_type, self._client._types.string_type],
            self._client._types.string_type
        )

    @StaticMethod
    def _return_type_static_method(cls) -> TypeBase:
        self = cls
        return self._client._types.string_type

    @StaticMethod
    def _build_call_static_method(cls, a: str = '', b: str = '') -> KRPC_pb2.ProcedureCall:
        self = cls
        return self._client._build_call(
            "TestService",
            "TestClass_static_StaticMethod",
            [a, b],
            [self._client._types.string_type, self._client._types.string_type],
            self._client._types.string_type
        )

    @StaticMethod
    def static_nullable_object(cls, value: Optional[TestClass]) -> Optional[TestClass]:
        self = cls
        return cls._client._invoke(
            "TestService",
            "TestClass_static_StaticNullableObject",
            [value],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    @StaticMethod
    def _return_type_static_nullable_object(cls) -> TypeBase:
        self = cls
        return self._client._types.class_type("TestService", "TestClass")

    @StaticMethod
    def _build_call_static_nullable_object(cls, value: Optional[TestClass]) -> KRPC_pb2.ProcedureCall:
        self = cls
        return self._client._build_call(
            "TestService",
            "TestClass_static_StaticNullableObject",
            [value],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )



# The classes, enumerations, structures and exceptions put on the service in
# __init__, declared for type checkers
if TYPE_CHECKING:
    _DeprecatedClass = DeprecatedClass
    _TestClass = TestClass
    _DeprecatedEnum = DeprecatedEnum
    _TestEnum = TestEnum
    _DeprecatedStruct = DeprecatedStruct
    _TestNestedNullableStruct = TestNestedNullableStruct
    _TestStruct = TestStruct
    _TestNestedStruct = TestNestedStruct
    _TestNullableStruct = TestNullableStruct
    _CustomException = CustomException
    _DeprecatedException = DeprecatedException

    class _TestServiceDefinitions:
        DeprecatedClass: type[_DeprecatedClass]
        TestClass: type[_TestClass]
        DeprecatedEnum: type[_DeprecatedEnum]
        TestEnum: type[_TestEnum]
        DeprecatedStruct: type[_DeprecatedStruct]
        TestNestedNullableStruct: type[_TestNestedNullableStruct]
        TestStruct: type[_TestStruct]
        TestNestedStruct: type[_TestNestedStruct]
        TestNullableStruct: type[_TestNullableStruct]
        CustomException: type[_CustomException]
        DeprecatedException: type[_DeprecatedException]
else:
    _TestServiceDefinitions = object


class TestService(_TestServiceDefinitions):
    """
    Service documentation string.
    """

    def __init__(self, client: Client) -> None:
        self._client = client
        # The classes, enumerations, structures and exceptions the service defines are
        # put on the service here, so that reaching one is an ordinary attribute lookup
        # and nothing has to intercept the lookups that do not name one - which is every
        # call, as a call goes through a procedure or a property. A class is bound to the
        # client it is reached through, so that its static methods use that client.
        self.__dict__.update(self._enumerations)
        self.__dict__.update(self._structs)
        self.__dict__.update(self._exceptions)
        for name, class_type in self._classes.items():
            self.__dict__[name] = WrappedClass(client, class_type)

    # Hidden from type checkers, so that they report a name the service does not define
    if not TYPE_CHECKING:

        def __getattr__(self, name):
            # Reached only once the ordinary lookup has failed, which for a service means
            # either a name it does not define, or one it does whose procedure or property
            # raised an AttributeError of its own. Python discards that error before calling
            # this, so it cannot be reported here; what can be done is to not report a member
            # that does exist as missing, which would point at the wrong thing entirely.
            cls = type(self)
            if hasattr(cls, name):
                raise AttributeError(
                    "'%s' object attribute '%s' raised AttributeError"
                    % (cls.__name__, name)
                )
            raise AttributeError(
                "'%s' object has no attribute '%s'" % (cls.__name__, name)
            )

    _classes = {
        "DeprecatedClass": DeprecatedClass,
        "TestClass": TestClass,
    }
    _enumerations = {
        "DeprecatedEnum": DeprecatedEnum,
        "TestEnum": TestEnum,
    }
    _structs = {
        "DeprecatedStruct": DeprecatedStruct,
        "TestNestedNullableStruct": TestNestedNullableStruct,
        "TestStruct": TestStruct,
        "TestNestedStruct": TestNestedStruct,
        "TestNullableStruct": TestNullableStruct,
    }
    _exceptions = {
        "CustomException": CustomException,
        "DeprecatedException": DeprecatedException,
    }

    @property
    def deprecated_property(self) -> str:
        """
        Deprecated. Use string_property instead.

        Deprecated property documentation string.
        """
        warnings.warn("TestService.deprecated_property is deprecated: Use string_property instead.", DeprecationWarning, stacklevel=2)
        return self._client._invoke(
            "TestService",
            "get_DeprecatedProperty",
            [],
            [],
            self._client._types.string_type
        )

    @deprecated_property.setter
    def deprecated_property(self, value: str) -> None:
        warnings.warn("TestService.deprecated_property is deprecated: Use string_property instead.", DeprecationWarning, stacklevel=2)
        return self._client._invoke(
            "TestService",
            "set_DeprecatedProperty",
            [value],
            [self._client._types.string_type],
            None
        )

    def _return_type_deprecated_property(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_deprecated_property(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "get_DeprecatedProperty",
            [],
            [],
            self._client._types.string_type
        )

    @property
    def nullable_object(self) -> Optional[TestClass]:
        return self._client._invoke(
            "TestService",
            "get_NullableObject",
            [],
            [],
            self._client._types.class_type("TestService", "TestClass")
        )

    @nullable_object.setter
    def nullable_object(self, value: Optional[TestClass]) -> None:
        return self._client._invoke(
            "TestService",
            "set_NullableObject",
            [value],
            [self._client._types.class_type("TestService", "TestClass")],
            None
        )

    def _return_type_nullable_object(self) -> TypeBase:
        return self._client._types.class_type("TestService", "TestClass")

    def _build_call_nullable_object(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "get_NullableObject",
            [],
            [],
            self._client._types.class_type("TestService", "TestClass")
        )

    @property
    def object_property(self) -> Optional[TestClass]:
        return self._client._invoke(
            "TestService",
            "get_ObjectProperty",
            [],
            [],
            self._client._types.class_type("TestService", "TestClass")
        )

    @object_property.setter
    def object_property(self, value: Optional[TestClass]) -> None:
        return self._client._invoke(
            "TestService",
            "set_ObjectProperty",
            [value],
            [self._client._types.class_type("TestService", "TestClass")],
            None
        )

    def _return_type_object_property(self) -> TypeBase:
        return self._client._types.class_type("TestService", "TestClass")

    def _build_call_object_property(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "get_ObjectProperty",
            [],
            [],
            self._client._types.class_type("TestService", "TestClass")
        )

    @property
    def string_property(self) -> str:
        """
        Property documentation string.
        """
        return self._client._invoke(
            "TestService",
            "get_StringProperty",
            [],
            [],
            self._client._types.string_type
        )

    @string_property.setter
    def string_property(self, value: str) -> None:
        return self._client._invoke(
            "TestService",
            "set_StringProperty",
            [value],
            [self._client._types.string_type],
            None
        )

    def _return_type_string_property(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_string_property(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "get_StringProperty",
            [],
            [],
            self._client._types.string_type
        )

    @property
    def string_property_private_get(self) -> str:
        raise NotImplementedError

    @string_property_private_get.setter
    def string_property_private_get(self, value: str) -> None:
        return self._client._invoke(
            "TestService",
            "set_StringPropertyPrivateGet",
            [value],
            [self._client._types.string_type],
            None
        )

    @property
    def string_property_private_set(self) -> str:
        return self._client._invoke(
            "TestService",
            "get_StringPropertyPrivateSet",
            [],
            [],
            self._client._types.string_type
        )

    def _return_type_string_property_private_set(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_string_property_private_set(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "get_StringPropertyPrivateSet",
            [],
            [],
            self._client._types.string_type
        )

    def add_multiple_values(self, x: float, y: int, z: int) -> str:
        return self._client._invoke(
            "TestService",
            "AddMultipleValues",
            [x, y, z],
            [self._client._types.float_type, self._client._types.sint32_type, self._client._types.sint64_type],
            self._client._types.string_type
        )

    def _return_type_add_multiple_values(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_add_multiple_values(self, x: float, y: int, z: int) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "AddMultipleValues",
            [x, y, z],
            [self._client._types.float_type, self._client._types.sint32_type, self._client._types.sint64_type],
            self._client._types.string_type
        )

    def add_to_object_list(self, l: List[TestClass], value: str) -> List[TestClass]:
        return self._client._invoke(
            "TestService",
            "AddToObjectList",
            [l, value],
            [self._client._types.list_type(self._client._types.class_type("TestService", "TestClass")), self._client._types.string_type],
            self._client._types.list_type(self._client._types.class_type("TestService", "TestClass"))
        )

    def _return_type_add_to_object_list(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.class_type("TestService", "TestClass"))

    def _build_call_add_to_object_list(self, l: List[TestClass], value: str) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "AddToObjectList",
            [l, value],
            [self._client._types.list_type(self._client._types.class_type("TestService", "TestClass")), self._client._types.string_type],
            self._client._types.list_type(self._client._types.class_type("TestService", "TestClass"))
        )

    def blocking_procedure(self, n: int, sum: int = 0) -> int:
        return self._client._invoke(
            "TestService",
            "BlockingProcedure",
            [n, sum],
            [self._client._types.sint32_type, self._client._types.sint32_type],
            self._client._types.sint32_type
        )

    def _return_type_blocking_procedure(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_blocking_procedure(self, n: int, sum: int = 0) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "BlockingProcedure",
            [n, sum],
            [self._client._types.sint32_type, self._client._types.sint32_type],
            self._client._types.sint32_type
        )

    def bool_to_string(self, value: bool) -> str:
        return self._client._invoke(
            "TestService",
            "BoolToString",
            [value],
            [self._client._types.bool_type],
            self._client._types.string_type
        )

    def _return_type_bool_to_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_bool_to_string(self, value: bool) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "BoolToString",
            [value],
            [self._client._types.bool_type],
            self._client._types.string_type
        )

    def bytes_to_hex_string(self, value: bytes) -> str:
        return self._client._invoke(
            "TestService",
            "BytesToHexString",
            [value],
            [self._client._types.bytes_type],
            self._client._types.string_type
        )

    def _return_type_bytes_to_hex_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_bytes_to_hex_string(self, value: bytes) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "BytesToHexString",
            [value],
            [self._client._types.bytes_type],
            self._client._types.string_type
        )

    def counter(self, id: str = '', divisor: int = 1) -> int:
        return self._client._invoke(
            "TestService",
            "Counter",
            [id, divisor],
            [self._client._types.string_type, self._client._types.sint32_type],
            self._client._types.sint32_type
        )

    def _return_type_counter(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_counter(self, id: str = '', divisor: int = 1) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "Counter",
            [id, divisor],
            [self._client._types.string_type, self._client._types.sint32_type],
            self._client._types.sint32_type
        )

    def counter_struct(self, id: str = '') -> TestStruct:
        """
        Returns a struct whose IntField counts the number of times it has been called,
        so that a stream on it changes on every update.
        """
        return self._client._invoke(
            "TestService",
            "CounterStruct",
            [id],
            [self._client._types.string_type],
            self._client._types.struct_type("TestService", "TestStruct")
        )

    def _return_type_counter_struct(self) -> TypeBase:
        return self._client._types.struct_type("TestService", "TestStruct")

    def _build_call_counter_struct(self, id: str = '') -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "CounterStruct",
            [id],
            [self._client._types.string_type],
            self._client._types.struct_type("TestService", "TestStruct")
        )

    def create_test_object(self, value: str) -> TestClass:
        return self._client._invoke(
            "TestService",
            "CreateTestObject",
            [value],
            [self._client._types.string_type],
            self._client._types.class_type("TestService", "TestClass")
        )

    def _return_type_create_test_object(self) -> TypeBase:
        return self._client._types.class_type("TestService", "TestClass")

    def _build_call_create_test_object(self, value: str) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "CreateTestObject",
            [value],
            [self._client._types.string_type],
            self._client._types.class_type("TestService", "TestClass")
        )

    def deprecated_procedure(self, value: float) -> str:
        """
        Deprecated. Use float_to_string instead.

        Deprecated procedure documentation string.
        """
        warnings.warn("TestService.deprecated_procedure is deprecated: Use float_to_string instead.", DeprecationWarning, stacklevel=2)
        return self._client._invoke(
            "TestService",
            "DeprecatedProcedure",
            [value],
            [self._client._types.float_type],
            self._client._types.string_type
        )

    def _return_type_deprecated_procedure(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_deprecated_procedure(self, value: float) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "DeprecatedProcedure",
            [value],
            [self._client._types.float_type],
            self._client._types.string_type
        )

    def deprecated_procedure_no_message(self, value: float) -> str:
        """
        Deprecated.

        Deprecated procedure with no reason documentation string.
        """
        warnings.warn("TestService.deprecated_procedure_no_message is deprecated", DeprecationWarning, stacklevel=2)
        return self._client._invoke(
            "TestService",
            "DeprecatedProcedureNoMessage",
            [value],
            [self._client._types.float_type],
            self._client._types.string_type
        )

    def _return_type_deprecated_procedure_no_message(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_deprecated_procedure_no_message(self, value: float) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "DeprecatedProcedureNoMessage",
            [value],
            [self._client._types.float_type],
            self._client._types.string_type
        )

    def dictionary_default(self, x: Dict[int, bool] = {1: False, 2: True}) -> Dict[int, bool]:
        return self._client._invoke(
            "TestService",
            "DictionaryDefault",
            [x],
            [self._client._types.dictionary_type(self._client._types.sint32_type, self._client._types.bool_type)],
            self._client._types.dictionary_type(self._client._types.sint32_type, self._client._types.bool_type)
        )

    def _return_type_dictionary_default(self) -> TypeBase:
        return self._client._types.dictionary_type(self._client._types.sint32_type, self._client._types.bool_type)

    def _build_call_dictionary_default(self, x: Dict[int, bool] = {1: False, 2: True}) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "DictionaryDefault",
            [x],
            [self._client._types.dictionary_type(self._client._types.sint32_type, self._client._types.bool_type)],
            self._client._types.dictionary_type(self._client._types.sint32_type, self._client._types.bool_type)
        )

    def double_special_defaults(self, nan: float = float("nan"), infinity: float = float("inf"), negative_infinity: float = -float("inf"), maximum: float = krpc.limits.DOUBLE_MAX, lowest: float = krpc.limits.DOUBLE_LOWEST) -> List[float]:
        """
        Procedure whose defaults are the special values of double.
        """
        return self._client._invoke(
            "TestService",
            "DoubleSpecialDefaults",
            [nan, infinity, negative_infinity, maximum, lowest],
            [self._client._types.double_type, self._client._types.double_type, self._client._types.double_type, self._client._types.double_type, self._client._types.double_type],
            self._client._types.list_type(self._client._types.double_type)
        )

    def _return_type_double_special_defaults(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.double_type)

    def _build_call_double_special_defaults(self, nan: float = float("nan"), infinity: float = float("inf"), negative_infinity: float = -float("inf"), maximum: float = krpc.limits.DOUBLE_MAX, lowest: float = krpc.limits.DOUBLE_LOWEST) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "DoubleSpecialDefaults",
            [nan, infinity, negative_infinity, maximum, lowest],
            [self._client._types.double_type, self._client._types.double_type, self._client._types.double_type, self._client._types.double_type, self._client._types.double_type],
            self._client._types.list_type(self._client._types.double_type)
        )

    def double_to_string(self, value: float) -> str:
        return self._client._invoke(
            "TestService",
            "DoubleToString",
            [value],
            [self._client._types.double_type],
            self._client._types.string_type
        )

    def _return_type_double_to_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_double_to_string(self, value: float) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "DoubleToString",
            [value],
            [self._client._types.double_type],
            self._client._types.string_type
        )

    def dump_expression_tree(self, expression: _service_krpc.Expression) -> str:
        """
        The expression tree of a function, as text.
        """
        return self._client._invoke(
            "TestService",
            "DumpExpressionTree",
            [expression],
            [self._client._types.class_type("KRPC", "Expression")],
            self._client._types.string_type
        )

    def _return_type_dump_expression_tree(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_dump_expression_tree(self, expression: _service_krpc.Expression) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "DumpExpressionTree",
            [expression],
            [self._client._types.class_type("KRPC", "Expression")],
            self._client._types.string_type
        )

    def echo_dictionary_of_nullable_objects(self, d: Dict[str, Optional[TestClass]]) -> Dict[str, Optional[TestClass]]:
        return self._client._invoke(
            "TestService",
            "EchoDictionaryOfNullableObjects",
            [d],
            [self._client._types.dictionary_type(self._client._types.string_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))],
            self._client._types.dictionary_type(self._client._types.string_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))
        )

    def _return_type_echo_dictionary_of_nullable_objects(self) -> TypeBase:
        return self._client._types.dictionary_type(self._client._types.string_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))

    def _build_call_echo_dictionary_of_nullable_objects(self, d: Dict[str, Optional[TestClass]]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoDictionaryOfNullableObjects",
            [d],
            [self._client._types.dictionary_type(self._client._types.string_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))],
            self._client._types.dictionary_type(self._client._types.string_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))
        )

    def echo_list_of_nullable_ints(self, l: List[Optional[int]]) -> List[Optional[int]]:
        return self._client._invoke(
            "TestService",
            "EchoListOfNullableInts",
            [l],
            [self._client._types.list_type(self._client._types.nullable(self._client._types.sint32_type))],
            self._client._types.list_type(self._client._types.nullable(self._client._types.sint32_type))
        )

    def _return_type_echo_list_of_nullable_ints(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.nullable(self._client._types.sint32_type))

    def _build_call_echo_list_of_nullable_ints(self, l: List[Optional[int]]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoListOfNullableInts",
            [l],
            [self._client._types.list_type(self._client._types.nullable(self._client._types.sint32_type))],
            self._client._types.list_type(self._client._types.nullable(self._client._types.sint32_type))
        )

    def echo_list_of_nullable_objects(self, l: List[Optional[TestClass]]) -> List[Optional[TestClass]]:
        return self._client._invoke(
            "TestService",
            "EchoListOfNullableObjects",
            [l],
            [self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))],
            self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))
        )

    def _return_type_echo_list_of_nullable_objects(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))

    def _build_call_echo_list_of_nullable_objects(self, l: List[Optional[TestClass]]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoListOfNullableObjects",
            [l],
            [self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))],
            self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))
        )

    def echo_nested_list_of_nullable_objects(self, l: List[List[Optional[TestClass]]]) -> List[List[Optional[TestClass]]]:
        return self._client._invoke(
            "TestService",
            "EchoNestedListOfNullableObjects",
            [l],
            [self._client._types.list_type(self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass"))))],
            self._client._types.list_type(self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass"))))
        )

    def _return_type_echo_nested_list_of_nullable_objects(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass"))))

    def _build_call_echo_nested_list_of_nullable_objects(self, l: List[List[Optional[TestClass]]]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoNestedListOfNullableObjects",
            [l],
            [self._client._types.list_type(self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass"))))],
            self._client._types.list_type(self._client._types.list_type(self._client._types.nullable(self._client._types.class_type("TestService", "TestClass"))))
        )

    def echo_nested_nullable_struct(self, value: TestNestedNullableStruct) -> TestNestedNullableStruct:
        return self._client._invoke(
            "TestService",
            "EchoNestedNullableStruct",
            [value],
            [self._client._types.struct_type("TestService", "TestNestedNullableStruct")],
            self._client._types.struct_type("TestService", "TestNestedNullableStruct")
        )

    def _return_type_echo_nested_nullable_struct(self) -> TypeBase:
        return self._client._types.struct_type("TestService", "TestNestedNullableStruct")

    def _build_call_echo_nested_nullable_struct(self, value: TestNestedNullableStruct) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoNestedNullableStruct",
            [value],
            [self._client._types.struct_type("TestService", "TestNestedNullableStruct")],
            self._client._types.struct_type("TestService", "TestNestedNullableStruct")
        )

    def echo_nullable_int(self, value: Optional[int]) -> Optional[int]:
        return self._client._invoke(
            "TestService",
            "EchoNullableInt",
            [value],
            [self._client._types.sint32_type],
            self._client._types.sint32_type
        )

    def _return_type_echo_nullable_int(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_echo_nullable_int(self, value: Optional[int]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoNullableInt",
            [value],
            [self._client._types.sint32_type],
            self._client._types.sint32_type
        )

    def echo_nullable_list(self, l: Optional[List[int]]) -> Optional[List[int]]:
        return self._client._invoke(
            "TestService",
            "EchoNullableList",
            [l],
            [self._client._types.list_type(self._client._types.sint32_type)],
            self._client._types.list_type(self._client._types.sint32_type)
        )

    def _return_type_echo_nullable_list(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.sint32_type)

    def _build_call_echo_nullable_list(self, l: Optional[List[int]]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoNullableList",
            [l],
            [self._client._types.list_type(self._client._types.sint32_type)],
            self._client._types.list_type(self._client._types.sint32_type)
        )

    def echo_nullable_string(self, value: Optional[str]) -> Optional[str]:
        return self._client._invoke(
            "TestService",
            "EchoNullableString",
            [value],
            [self._client._types.string_type],
            self._client._types.string_type
        )

    def _return_type_echo_nullable_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_echo_nullable_string(self, value: Optional[str]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoNullableString",
            [value],
            [self._client._types.string_type],
            self._client._types.string_type
        )

    def echo_test_object(self, value: Optional[TestClass]) -> Optional[TestClass]:
        return self._client._invoke(
            "TestService",
            "EchoTestObject",
            [value],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    def _return_type_echo_test_object(self) -> TypeBase:
        return self._client._types.class_type("TestService", "TestClass")

    def _build_call_echo_test_object(self, value: Optional[TestClass]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoTestObject",
            [value],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    def echo_tuple_with_a_nullable_object(self, t: Tuple[int,Optional[TestClass]]) -> Tuple[int,Optional[TestClass]]:
        return self._client._invoke(
            "TestService",
            "EchoTupleWithANullableObject",
            [t],
            [self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))],
            self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))
        )

    def _return_type_echo_tuple_with_a_nullable_object(self) -> TypeBase:
        return self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))

    def _build_call_echo_tuple_with_a_nullable_object(self, t: Tuple[int,Optional[TestClass]]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EchoTupleWithANullableObject",
            [t],
            [self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))],
            self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.nullable(self._client._types.class_type("TestService", "TestClass")))
        )

    def empty_list_default(self, x: List[str] = []) -> List[str]:
        return self._client._invoke(
            "TestService",
            "EmptyListDefault",
            [x],
            [self._client._types.list_type(self._client._types.string_type)],
            self._client._types.list_type(self._client._types.string_type)
        )

    def _return_type_empty_list_default(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.string_type)

    def _build_call_empty_list_default(self, x: List[str] = []) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EmptyListDefault",
            [x],
            [self._client._types.list_type(self._client._types.string_type)],
            self._client._types.list_type(self._client._types.string_type)
        )

    def enum_default_arg(self, x: TestEnum = TestEnum.value_c) -> TestEnum:
        return self._client._invoke(
            "TestService",
            "EnumDefaultArg",
            [x],
            [self._client._types.enumeration_type("TestService", "TestEnum")],
            self._client._types.enumeration_type("TestService", "TestEnum")
        )

    def _return_type_enum_default_arg(self) -> TypeBase:
        return self._client._types.enumeration_type("TestService", "TestEnum")

    def _build_call_enum_default_arg(self, x: TestEnum = TestEnum.value_c) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EnumDefaultArg",
            [x],
            [self._client._types.enumeration_type("TestService", "TestEnum")],
            self._client._types.enumeration_type("TestService", "TestEnum")
        )

    def enum_echo(self, x: TestEnum) -> TestEnum:
        return self._client._invoke(
            "TestService",
            "EnumEcho",
            [x],
            [self._client._types.enumeration_type("TestService", "TestEnum")],
            self._client._types.enumeration_type("TestService", "TestEnum")
        )

    def _return_type_enum_echo(self) -> TypeBase:
        return self._client._types.enumeration_type("TestService", "TestEnum")

    def _build_call_enum_echo(self, x: TestEnum) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EnumEcho",
            [x],
            [self._client._types.enumeration_type("TestService", "TestEnum")],
            self._client._types.enumeration_type("TestService", "TestEnum")
        )

    def enum_list_default(self, x: List[TestEnum] = [TestEnum.value_b, TestEnum.value_c]) -> List[TestEnum]:
        return self._client._invoke(
            "TestService",
            "EnumListDefault",
            [x],
            [self._client._types.list_type(self._client._types.enumeration_type("TestService", "TestEnum"))],
            self._client._types.list_type(self._client._types.enumeration_type("TestService", "TestEnum"))
        )

    def _return_type_enum_list_default(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.enumeration_type("TestService", "TestEnum"))

    def _build_call_enum_list_default(self, x: List[TestEnum] = [TestEnum.value_b, TestEnum.value_c]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EnumListDefault",
            [x],
            [self._client._types.list_type(self._client._types.enumeration_type("TestService", "TestEnum"))],
            self._client._types.list_type(self._client._types.enumeration_type("TestService", "TestEnum"))
        )

    def enum_return(self) -> TestEnum:
        return self._client._invoke(
            "TestService",
            "EnumReturn",
            [],
            [],
            self._client._types.enumeration_type("TestService", "TestEnum")
        )

    def _return_type_enum_return(self) -> TypeBase:
        return self._client._types.enumeration_type("TestService", "TestEnum")

    def _build_call_enum_return(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "EnumReturn",
            [],
            [],
            self._client._types.enumeration_type("TestService", "TestEnum")
        )

    def float_special_defaults(self, nan: float = float("nan"), infinity: float = float("inf"), negative_infinity: float = -float("inf"), maximum: float = krpc.limits.FLOAT_MAX, lowest: float = krpc.limits.FLOAT_LOWEST, fraction: float = 0.1) -> List[float]:
        """
        Procedure whose defaults are the special values of float, plus a finite fraction
        that no float can hold exactly.
        """
        return self._client._invoke(
            "TestService",
            "FloatSpecialDefaults",
            [nan, infinity, negative_infinity, maximum, lowest, fraction],
            [self._client._types.float_type, self._client._types.float_type, self._client._types.float_type, self._client._types.float_type, self._client._types.float_type, self._client._types.float_type],
            self._client._types.list_type(self._client._types.float_type)
        )

    def _return_type_float_special_defaults(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.float_type)

    def _build_call_float_special_defaults(self, nan: float = float("nan"), infinity: float = float("inf"), negative_infinity: float = -float("inf"), maximum: float = krpc.limits.FLOAT_MAX, lowest: float = krpc.limits.FLOAT_LOWEST, fraction: float = 0.1) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "FloatSpecialDefaults",
            [nan, infinity, negative_infinity, maximum, lowest, fraction],
            [self._client._types.float_type, self._client._types.float_type, self._client._types.float_type, self._client._types.float_type, self._client._types.float_type, self._client._types.float_type],
            self._client._types.list_type(self._client._types.float_type)
        )

    def float_to_string(self, value: float) -> str:
        """
        Procedure documentation string.
        """
        return self._client._invoke(
            "TestService",
            "FloatToString",
            [value],
            [self._client._types.float_type],
            self._client._types.string_type
        )

    def _return_type_float_to_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_float_to_string(self, value: float) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "FloatToString",
            [value],
            [self._client._types.float_type],
            self._client._types.string_type
        )

    def increment_dictionary(self, d: Dict[str, int]) -> Dict[str, int]:
        return self._client._invoke(
            "TestService",
            "IncrementDictionary",
            [d],
            [self._client._types.dictionary_type(self._client._types.string_type, self._client._types.sint32_type)],
            self._client._types.dictionary_type(self._client._types.string_type, self._client._types.sint32_type)
        )

    def _return_type_increment_dictionary(self) -> TypeBase:
        return self._client._types.dictionary_type(self._client._types.string_type, self._client._types.sint32_type)

    def _build_call_increment_dictionary(self, d: Dict[str, int]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "IncrementDictionary",
            [d],
            [self._client._types.dictionary_type(self._client._types.string_type, self._client._types.sint32_type)],
            self._client._types.dictionary_type(self._client._types.string_type, self._client._types.sint32_type)
        )

    def increment_list(self, l: List[int]) -> List[int]:
        return self._client._invoke(
            "TestService",
            "IncrementList",
            [l],
            [self._client._types.list_type(self._client._types.sint32_type)],
            self._client._types.list_type(self._client._types.sint32_type)
        )

    def _return_type_increment_list(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.sint32_type)

    def _build_call_increment_list(self, l: List[int]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "IncrementList",
            [l],
            [self._client._types.list_type(self._client._types.sint32_type)],
            self._client._types.list_type(self._client._types.sint32_type)
        )

    def increment_list_of_structs(self, l: List[TestStruct]) -> List[TestStruct]:
        return self._client._invoke(
            "TestService",
            "IncrementListOfStructs",
            [l],
            [self._client._types.list_type(self._client._types.struct_type("TestService", "TestStruct"))],
            self._client._types.list_type(self._client._types.struct_type("TestService", "TestStruct"))
        )

    def _return_type_increment_list_of_structs(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.struct_type("TestService", "TestStruct"))

    def _build_call_increment_list_of_structs(self, l: List[TestStruct]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "IncrementListOfStructs",
            [l],
            [self._client._types.list_type(self._client._types.struct_type("TestService", "TestStruct"))],
            self._client._types.list_type(self._client._types.struct_type("TestService", "TestStruct"))
        )

    def increment_nested_collection(self, d: Dict[str, List[int]]) -> Dict[str, List[int]]:
        return self._client._invoke(
            "TestService",
            "IncrementNestedCollection",
            [d],
            [self._client._types.dictionary_type(self._client._types.string_type, self._client._types.list_type(self._client._types.sint32_type))],
            self._client._types.dictionary_type(self._client._types.string_type, self._client._types.list_type(self._client._types.sint32_type))
        )

    def _return_type_increment_nested_collection(self) -> TypeBase:
        return self._client._types.dictionary_type(self._client._types.string_type, self._client._types.list_type(self._client._types.sint32_type))

    def _build_call_increment_nested_collection(self, d: Dict[str, List[int]]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "IncrementNestedCollection",
            [d],
            [self._client._types.dictionary_type(self._client._types.string_type, self._client._types.list_type(self._client._types.sint32_type))],
            self._client._types.dictionary_type(self._client._types.string_type, self._client._types.list_type(self._client._types.sint32_type))
        )

    def increment_set(self, h: Set[int]) -> Set[int]:
        return self._client._invoke(
            "TestService",
            "IncrementSet",
            [h],
            [self._client._types.set_type(self._client._types.sint32_type)],
            self._client._types.set_type(self._client._types.sint32_type)
        )

    def _return_type_increment_set(self) -> TypeBase:
        return self._client._types.set_type(self._client._types.sint32_type)

    def _build_call_increment_set(self, h: Set[int]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "IncrementSet",
            [h],
            [self._client._types.set_type(self._client._types.sint32_type)],
            self._client._types.set_type(self._client._types.sint32_type)
        )

    def increment_tuple(self, t: Tuple[int,int]) -> Tuple[int,int]:
        return self._client._invoke(
            "TestService",
            "IncrementTuple",
            [t],
            [self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.sint64_type)],
            self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.sint64_type)
        )

    def _return_type_increment_tuple(self) -> TypeBase:
        return self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.sint64_type)

    def _build_call_increment_tuple(self, t: Tuple[int,int]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "IncrementTuple",
            [t],
            [self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.sint64_type)],
            self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.sint64_type)
        )

    def int32_special_defaults(self, maximum: int = krpc.limits.SINT32_MAX, minimum: int = krpc.limits.SINT32_MIN) -> List[int]:
        """
        Procedure whose defaults are the extremes of int.
        """
        return self._client._invoke(
            "TestService",
            "Int32SpecialDefaults",
            [maximum, minimum],
            [self._client._types.sint32_type, self._client._types.sint32_type],
            self._client._types.list_type(self._client._types.sint32_type)
        )

    def _return_type_int32_special_defaults(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.sint32_type)

    def _build_call_int32_special_defaults(self, maximum: int = krpc.limits.SINT32_MAX, minimum: int = krpc.limits.SINT32_MIN) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "Int32SpecialDefaults",
            [maximum, minimum],
            [self._client._types.sint32_type, self._client._types.sint32_type],
            self._client._types.list_type(self._client._types.sint32_type)
        )

    def int32_to_string(self, value: int) -> str:
        return self._client._invoke(
            "TestService",
            "Int32ToString",
            [value],
            [self._client._types.sint32_type],
            self._client._types.string_type
        )

    def _return_type_int32_to_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_int32_to_string(self, value: int) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "Int32ToString",
            [value],
            [self._client._types.sint32_type],
            self._client._types.string_type
        )

    def int64_special_defaults(self, maximum: int = krpc.limits.SINT64_MAX, minimum: int = krpc.limits.SINT64_MIN) -> List[int]:
        """
        Procedure whose defaults are the extremes of long.
        """
        return self._client._invoke(
            "TestService",
            "Int64SpecialDefaults",
            [maximum, minimum],
            [self._client._types.sint64_type, self._client._types.sint64_type],
            self._client._types.list_type(self._client._types.sint64_type)
        )

    def _return_type_int64_special_defaults(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.sint64_type)

    def _build_call_int64_special_defaults(self, maximum: int = krpc.limits.SINT64_MAX, minimum: int = krpc.limits.SINT64_MIN) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "Int64SpecialDefaults",
            [maximum, minimum],
            [self._client._types.sint64_type, self._client._types.sint64_type],
            self._client._types.list_type(self._client._types.sint64_type)
        )

    def int64_to_string(self, value: int) -> str:
        return self._client._invoke(
            "TestService",
            "Int64ToString",
            [value],
            [self._client._types.sint64_type],
            self._client._types.string_type
        )

    def _return_type_int64_to_string(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_int64_to_string(self, value: int) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "Int64ToString",
            [value],
            [self._client._types.sint64_type],
            self._client._types.string_type
        )

    def list_default(self, x: List[int] = [1, 2, 3]) -> List[int]:
        return self._client._invoke(
            "TestService",
            "ListDefault",
            [x],
            [self._client._types.list_type(self._client._types.sint32_type)],
            self._client._types.list_type(self._client._types.sint32_type)
        )

    def _return_type_list_default(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.sint32_type)

    def _build_call_list_default(self, x: List[int] = [1, 2, 3]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ListDefault",
            [x],
            [self._client._types.list_type(self._client._types.sint32_type)],
            self._client._types.list_type(self._client._types.sint32_type)
        )

    def nested_struct_echo(self, x: TestNestedStruct) -> TestNestedStruct:
        return self._client._invoke(
            "TestService",
            "NestedStructEcho",
            [x],
            [self._client._types.struct_type("TestService", "TestNestedStruct")],
            self._client._types.struct_type("TestService", "TestNestedStruct")
        )

    def _return_type_nested_struct_echo(self) -> TypeBase:
        return self._client._types.struct_type("TestService", "TestNestedStruct")

    def _build_call_nested_struct_echo(self, x: TestNestedStruct) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "NestedStructEcho",
            [x],
            [self._client._types.struct_type("TestService", "TestNestedStruct")],
            self._client._types.struct_type("TestService", "TestNestedStruct")
        )

    def not_nullable_object(self, value: TestClass) -> TestClass:
        return self._client._invoke(
            "TestService",
            "NotNullableObject",
            [value],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    def _return_type_not_nullable_object(self) -> TypeBase:
        return self._client._types.class_type("TestService", "TestClass")

    def _build_call_not_nullable_object(self, value: TestClass) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "NotNullableObject",
            [value],
            [self._client._types.class_type("TestService", "TestClass")],
            self._client._types.class_type("TestService", "TestClass")
        )

    def nullable_struct_echo(self, x: TestNullableStruct) -> TestNullableStruct:
        return self._client._invoke(
            "TestService",
            "NullableStructEcho",
            [x],
            [self._client._types.struct_type("TestService", "TestNullableStruct")],
            self._client._types.struct_type("TestService", "TestNullableStruct")
        )

    def _return_type_nullable_struct_echo(self) -> TypeBase:
        return self._client._types.struct_type("TestService", "TestNullableStruct")

    def _build_call_nullable_struct_echo(self, x: TestNullableStruct) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "NullableStructEcho",
            [x],
            [self._client._types.struct_type("TestService", "TestNullableStruct")],
            self._client._types.struct_type("TestService", "TestNullableStruct")
        )

    def on_timer(self, milliseconds: int, repeats: int = 1) -> Event:
        return self._client._invoke(
            "TestService",
            "OnTimer",
            [milliseconds, repeats],
            [self._client._types.uint32_type, self._client._types.uint32_type],
            self._client._types.event_type
        )

    def _return_type_on_timer(self) -> TypeBase:
        return self._client._types.event_type

    def _build_call_on_timer(self, milliseconds: int, repeats: int = 1) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "OnTimer",
            [milliseconds, repeats],
            [self._client._types.uint32_type, self._client._types.uint32_type],
            self._client._types.event_type
        )

    def on_timer_using_lambda(self, milliseconds: int) -> Event:
        return self._client._invoke(
            "TestService",
            "OnTimerUsingLambda",
            [milliseconds],
            [self._client._types.uint32_type],
            self._client._types.event_type
        )

    def _return_type_on_timer_using_lambda(self) -> TypeBase:
        return self._client._types.event_type

    def _build_call_on_timer_using_lambda(self, milliseconds: int) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "OnTimerUsingLambda",
            [milliseconds],
            [self._client._types.uint32_type],
            self._client._types.event_type
        )

    def optional_arguments(self, x: str, y: str = 'foo', z: str = 'bar', obj: Optional[TestClass] = None) -> str:
        return self._client._invoke(
            "TestService",
            "OptionalArguments",
            [x, y, z, obj],
            [self._client._types.string_type, self._client._types.string_type, self._client._types.string_type, self._client._types.class_type("TestService", "TestClass")],
            self._client._types.string_type
        )

    def _return_type_optional_arguments(self) -> TypeBase:
        return self._client._types.string_type

    def _build_call_optional_arguments(self, x: str, y: str = 'foo', z: str = 'bar', obj: Optional[TestClass] = None) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "OptionalArguments",
            [x, y, z, obj],
            [self._client._types.string_type, self._client._types.string_type, self._client._types.string_type, self._client._types.class_type("TestService", "TestClass")],
            self._client._types.string_type
        )

    def remove_event_after(self, milliseconds: int) -> Event:
        return self._client._invoke(
            "TestService",
            "RemoveEventAfter",
            [milliseconds],
            [self._client._types.uint32_type],
            self._client._types.event_type
        )

    def _return_type_remove_event_after(self) -> TypeBase:
        return self._client._types.event_type

    def _build_call_remove_event_after(self, milliseconds: int) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "RemoveEventAfter",
            [milliseconds],
            [self._client._types.uint32_type],
            self._client._types.event_type
        )

    def reset_custom_exception_later(self) -> None:
        return self._client._invoke(
            "TestService",
            "ResetCustomExceptionLater",
            [],
            [],
            None
        )

    def _return_type_reset_custom_exception_later(self) -> TypeBase:
        return None

    def _build_call_reset_custom_exception_later(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ResetCustomExceptionLater",
            [],
            [],
            None
        )

    def reset_invalid_operation_exception_later(self) -> None:
        return self._client._invoke(
            "TestService",
            "ResetInvalidOperationExceptionLater",
            [],
            [],
            None
        )

    def _return_type_reset_invalid_operation_exception_later(self) -> TypeBase:
        return None

    def _build_call_reset_invalid_operation_exception_later(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ResetInvalidOperationExceptionLater",
            [],
            [],
            None
        )

    def return_null_when_not_allowed(self) -> TestClass:
        return self._client._invoke(
            "TestService",
            "ReturnNullWhenNotAllowed",
            [],
            [],
            self._client._types.class_type("TestService", "TestClass")
        )

    def _return_type_return_null_when_not_allowed(self) -> TypeBase:
        return self._client._types.class_type("TestService", "TestClass")

    def _build_call_return_null_when_not_allowed(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ReturnNullWhenNotAllowed",
            [],
            [],
            self._client._types.class_type("TestService", "TestClass")
        )

    def set_default(self, x: Set[int] = {1, 2, 3}) -> Set[int]:
        return self._client._invoke(
            "TestService",
            "SetDefault",
            [x],
            [self._client._types.set_type(self._client._types.sint32_type)],
            self._client._types.set_type(self._client._types.sint32_type)
        )

    def _return_type_set_default(self) -> TypeBase:
        return self._client._types.set_type(self._client._types.sint32_type)

    def _build_call_set_default(self, x: Set[int] = {1, 2, 3}) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "SetDefault",
            [x],
            [self._client._types.set_type(self._client._types.sint32_type)],
            self._client._types.set_type(self._client._types.sint32_type)
        )

    def string_to_int32(self, value: str) -> int:
        return self._client._invoke(
            "TestService",
            "StringToInt32",
            [value],
            [self._client._types.string_type],
            self._client._types.sint32_type
        )

    def _return_type_string_to_int32(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_string_to_int32(self, value: str) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "StringToInt32",
            [value],
            [self._client._types.string_type],
            self._client._types.sint32_type
        )

    def struct_default(self, x: TestStruct = TestStruct(42, 'jeb', TestEnum.value_b, [1, 2, 3])) -> TestStruct:
        return self._client._invoke(
            "TestService",
            "StructDefault",
            [x],
            [self._client._types.struct_type("TestService", "TestStruct")],
            self._client._types.struct_type("TestService", "TestStruct")
        )

    def _return_type_struct_default(self) -> TypeBase:
        return self._client._types.struct_type("TestService", "TestStruct")

    def _build_call_struct_default(self, x: TestStruct = TestStruct(42, 'jeb', TestEnum.value_b, [1, 2, 3])) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "StructDefault",
            [x],
            [self._client._types.struct_type("TestService", "TestStruct")],
            self._client._types.struct_type("TestService", "TestStruct")
        )

    def struct_echo(self, x: TestStruct) -> TestStruct:
        return self._client._invoke(
            "TestService",
            "StructEcho",
            [x],
            [self._client._types.struct_type("TestService", "TestStruct")],
            self._client._types.struct_type("TestService", "TestStruct")
        )

    def _return_type_struct_echo(self) -> TypeBase:
        return self._client._types.struct_type("TestService", "TestStruct")

    def _build_call_struct_echo(self, x: TestStruct) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "StructEcho",
            [x],
            [self._client._types.struct_type("TestService", "TestStruct")],
            self._client._types.struct_type("TestService", "TestStruct")
        )

    def struct_echo_nullable(self, x: Optional[TestStruct]) -> Optional[TestStruct]:
        return self._client._invoke(
            "TestService",
            "StructEchoNullable",
            [x],
            [self._client._types.struct_type("TestService", "TestStruct")],
            self._client._types.struct_type("TestService", "TestStruct")
        )

    def _return_type_struct_echo_nullable(self) -> TypeBase:
        return self._client._types.struct_type("TestService", "TestStruct")

    def _build_call_struct_echo_nullable(self, x: Optional[TestStruct]) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "StructEchoNullable",
            [x],
            [self._client._types.struct_type("TestService", "TestStruct")],
            self._client._types.struct_type("TestService", "TestStruct")
        )

    def throw_argument_exception(self) -> int:
        return self._client._invoke(
            "TestService",
            "ThrowArgumentException",
            [],
            [],
            self._client._types.sint32_type
        )

    def _return_type_throw_argument_exception(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_throw_argument_exception(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ThrowArgumentException",
            [],
            [],
            self._client._types.sint32_type
        )

    def throw_argument_null_exception(self, foo: str) -> int:
        return self._client._invoke(
            "TestService",
            "ThrowArgumentNullException",
            [foo],
            [self._client._types.string_type],
            self._client._types.sint32_type
        )

    def _return_type_throw_argument_null_exception(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_throw_argument_null_exception(self, foo: str) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ThrowArgumentNullException",
            [foo],
            [self._client._types.string_type],
            self._client._types.sint32_type
        )

    def throw_argument_out_of_range_exception(self, foo: int) -> int:
        return self._client._invoke(
            "TestService",
            "ThrowArgumentOutOfRangeException",
            [foo],
            [self._client._types.sint32_type],
            self._client._types.sint32_type
        )

    def _return_type_throw_argument_out_of_range_exception(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_throw_argument_out_of_range_exception(self, foo: int) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ThrowArgumentOutOfRangeException",
            [foo],
            [self._client._types.sint32_type],
            self._client._types.sint32_type
        )

    def throw_custom_exception(self) -> int:
        return self._client._invoke(
            "TestService",
            "ThrowCustomException",
            [],
            [],
            self._client._types.sint32_type
        )

    def _return_type_throw_custom_exception(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_throw_custom_exception(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ThrowCustomException",
            [],
            [],
            self._client._types.sint32_type
        )

    def throw_custom_exception_later(self) -> int:
        return self._client._invoke(
            "TestService",
            "ThrowCustomExceptionLater",
            [],
            [],
            self._client._types.sint32_type
        )

    def _return_type_throw_custom_exception_later(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_throw_custom_exception_later(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ThrowCustomExceptionLater",
            [],
            [],
            self._client._types.sint32_type
        )

    def throw_invalid_operation_exception(self) -> int:
        return self._client._invoke(
            "TestService",
            "ThrowInvalidOperationException",
            [],
            [],
            self._client._types.sint32_type
        )

    def _return_type_throw_invalid_operation_exception(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_throw_invalid_operation_exception(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ThrowInvalidOperationException",
            [],
            [],
            self._client._types.sint32_type
        )

    def throw_invalid_operation_exception_later(self) -> int:
        return self._client._invoke(
            "TestService",
            "ThrowInvalidOperationExceptionLater",
            [],
            [],
            self._client._types.sint32_type
        )

    def _return_type_throw_invalid_operation_exception_later(self) -> TypeBase:
        return self._client._types.sint32_type

    def _build_call_throw_invalid_operation_exception_later(self) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "ThrowInvalidOperationExceptionLater",
            [],
            [],
            self._client._types.sint32_type
        )

    def tuple_default(self, x: Tuple[int,bool] = (1, False)) -> Tuple[int,bool]:
        return self._client._invoke(
            "TestService",
            "TupleDefault",
            [x],
            [self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.bool_type)],
            self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.bool_type)
        )

    def _return_type_tuple_default(self) -> TypeBase:
        return self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.bool_type)

    def _build_call_tuple_default(self, x: Tuple[int,bool] = (1, False)) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "TupleDefault",
            [x],
            [self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.bool_type)],
            self._client._types.tuple_type(self._client._types.sint32_type, self._client._types.bool_type)
        )

    def uint32_special_defaults(self, maximum: int = krpc.limits.UINT32_MAX) -> List[int]:
        """
        Procedure whose default is the largest uint.
        """
        return self._client._invoke(
            "TestService",
            "Uint32SpecialDefaults",
            [maximum],
            [self._client._types.uint32_type],
            self._client._types.list_type(self._client._types.uint32_type)
        )

    def _return_type_uint32_special_defaults(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.uint32_type)

    def _build_call_uint32_special_defaults(self, maximum: int = krpc.limits.UINT32_MAX) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "Uint32SpecialDefaults",
            [maximum],
            [self._client._types.uint32_type],
            self._client._types.list_type(self._client._types.uint32_type)
        )

    def uint64_special_defaults(self, maximum: int = krpc.limits.UINT64_MAX) -> List[int]:
        """
        Procedure whose default is the largest ulong.
        """
        return self._client._invoke(
            "TestService",
            "Uint64SpecialDefaults",
            [maximum],
            [self._client._types.uint64_type],
            self._client._types.list_type(self._client._types.uint64_type)
        )

    def _return_type_uint64_special_defaults(self) -> TypeBase:
        return self._client._types.list_type(self._client._types.uint64_type)

    def _build_call_uint64_special_defaults(self, maximum: int = krpc.limits.UINT64_MAX) -> KRPC_pb2.ProcedureCall:
        return self._client._build_call(
            "TestService",
            "Uint64SpecialDefaults",
            [maximum],
            [self._client._types.uint64_type],
            self._client._types.list_type(self._client._types.uint64_type)
        )
