from collections.abc import Callable
from concurrent.futures import Future

from google.protobuf.descriptor import MethodDescriptor, ServiceDescriptor
from google.protobuf.message import Message

class RpcException(Exception): ...

class Service:
    @staticmethod
    def GetDescriptor() -> ServiceDescriptor: ...
    def CallMethod(
        self,
        method_descriptor: MethodDescriptor,
        rpc_controller: RpcController,
        request: Message,
        done: Callable[[Message], None] | None,
    ) -> Future[Message] | None: ...
    def GetRequestClass(self, method_descriptor: MethodDescriptor) -> type[Message]: ...
    def GetResponseClass(self, method_descriptor: MethodDescriptor) -> type[Message]: ...

class RpcController:
    def Reset(self) -> None: ...
    def Failed(self) -> bool: ...
    def ErrorText(self) -> str | None: ...
    def StartCancel(self) -> None: ...
    def SetFailed(self, reason: str) -> None: ...
    def IsCanceled(self) -> bool: ...
    def NotifyOnCancel(self, callback: Callable[[], None]) -> None: ...

class RpcChannel:
    def CallMethod(
        self,
        method_descriptor: MethodDescriptor,
        rpc_controller: RpcController,
        request: Message,
        response_class: type[Message],
        done: Callable[[Message], None] | None,
    ) -> Future[Message] | None: ...
