# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: v1alpha/signature.proto
# plugin: python-betterproto
from dataclasses import dataclass
from typing import (
    TYPE_CHECKING,
    Dict,
    List,
    Optional,
)

import betterproto
import grpclib
from betterproto.grpc.grpclib_server import ServiceBase

from .. import graph as _graph__


if TYPE_CHECKING:
    import grpclib.server
    from betterproto.grpc.grpclib_client import MetadataLike
    from grpclib.metadata import Deadline


@dataclass(eq=False, repr=False)
class FunctionDeclaration(betterproto.Message):
    type_scheme: "_graph__.TypeScheme" = betterproto.message_field(2)
    description: str = betterproto.string_field(3)
    input_order: List[str] = betterproto.string_field(4)
    output_order: List[str] = betterproto.string_field(5)


@dataclass(eq=False, repr=False)
class ListFunctionsRequest(betterproto.Message):
    loc: "_graph__.Location" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class ListFunctionsResponse(betterproto.Message):
    root: "Namespace" = betterproto.message_field(1)
    aliases: Dict[str, "_graph__.TypeScheme"] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    scopes: List["_graph__.Location"] = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class InferTypeRequest(betterproto.Message):
    value: "_graph__.Value" = betterproto.message_field(1)
    loc: "_graph__.Location" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class InferTypeResponse(betterproto.Message):
    success: "InferTypeSuccess" = betterproto.message_field(1, group="response")
    error: "TypeErrors" = betterproto.message_field(2, group="response")


@dataclass(eq=False, repr=False)
class InferTypeSuccess(betterproto.Message):
    value: "_graph__.Value" = betterproto.message_field(1)
    type_scheme: "_graph__.TypeScheme" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class GraphWithInputs(betterproto.Message):
    graph: "_graph__.Graph" = betterproto.message_field(1)
    inputs: Optional["_graph__.StructValue"] = betterproto.message_field(
        2, optional=True, group="_inputs"
    )


@dataclass(eq=False, repr=False)
class InferGraphTypesRequest(betterproto.Message):
    gwi: "GraphWithInputs" = betterproto.message_field(1)
    functions: "Namespace" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class InferGraphTypesResponse(betterproto.Message):
    success: "GraphWithInputs" = betterproto.message_field(1, group="response")
    error: "TypeErrors" = betterproto.message_field(2, group="response")


@dataclass(eq=False, repr=False)
class Empty(betterproto.Message):
    """
    This is supposed to be `google.protobuf.Empty` but unfortunately there is
    no support for this in `betterproto` yet.
    """

    pass


@dataclass(eq=False, repr=False)
class GraphLocation(betterproto.Message):
    root: "Empty" = betterproto.message_field(1, group="location")
    vec_index: int = betterproto.uint32_field(2, group="location")
    node_idx: int = betterproto.uint32_field(4, group="location")
    edge: "_graph__.Edge" = betterproto.message_field(5, group="location")
    input: "Empty" = betterproto.message_field(6, group="location")
    output: "Empty" = betterproto.message_field(7, group="location")
    struct_field: str = betterproto.string_field(8, group="location")
    pair_first: "Empty" = betterproto.message_field(9, group="location")
    pair_second: "Empty" = betterproto.message_field(10, group="location")
    map_key: "Empty" = betterproto.message_field(11, group="location")
    map_value: "Empty" = betterproto.message_field(12, group="location")
    input_value: str = betterproto.string_field(13, group="location")


@dataclass(eq=False, repr=False)
class TypeErrors(betterproto.Message):
    errors: List["TierkreisTypeError"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class UnifyError(betterproto.Message):
    expected: "_graph__.Type" = betterproto.message_field(1)
    found: "_graph__.Type" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class TypeVarError(betterproto.Message):
    variable: "_graph__.TypeSchemeVar" = betterproto.message_field(1)
    type_scheme: "_graph__.TypeScheme" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class ErrorVariant(betterproto.Message):
    unify: "UnifyError" = betterproto.message_field(1, group="error")
    kind: str = betterproto.string_field(2, group="error")
    unknown_function: "_graph__.FunctionName" = betterproto.message_field(
        3, group="error"
    )
    unknown_type_var: "TypeVarError" = betterproto.message_field(4, group="error")
    bound: str = betterproto.string_field(5, group="error")


@dataclass(eq=False, repr=False)
class TierkreisTypeError(betterproto.Message):
    variant: "ErrorVariant" = betterproto.message_field(1)
    location: List["GraphLocation"] = betterproto.message_field(2)
    """locations go from outermost to innermost in nested const/box graphs"""


@dataclass(eq=False, repr=False)
class NamespaceItem(betterproto.Message):
    decl: "FunctionDeclaration" = betterproto.message_field(1)
    locations: List["_graph__.Location"] = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class Namespace(betterproto.Message):
    functions: Dict[str, "NamespaceItem"] = betterproto.map_field(
        1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    subspaces: Dict[str, "Namespace"] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )


class SignatureStub(betterproto.ServiceStub):
    async def list_functions(
        self,
        list_functions_request: "ListFunctionsRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "ListFunctionsResponse":
        return await self._unary_unary(
            "/tierkreis.v1alpha.signature.Signature/ListFunctions",
            list_functions_request,
            ListFunctionsResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class TypeInferenceStub(betterproto.ServiceStub):
    async def infer_type(
        self,
        infer_type_request: "InferTypeRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "InferTypeResponse":
        return await self._unary_unary(
            "/tierkreis.v1alpha.signature.TypeInference/InferType",
            infer_type_request,
            InferTypeResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class SignatureBase(ServiceBase):
    async def list_functions(
        self, list_functions_request: "ListFunctionsRequest"
    ) -> "ListFunctionsResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_list_functions(
        self,
        stream: "grpclib.server.Stream[ListFunctionsRequest, ListFunctionsResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.list_functions(request)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/tierkreis.v1alpha.signature.Signature/ListFunctions": grpclib.const.Handler(
                self.__rpc_list_functions,
                grpclib.const.Cardinality.UNARY_UNARY,
                ListFunctionsRequest,
                ListFunctionsResponse,
            ),
        }


class TypeInferenceBase(ServiceBase):
    async def infer_type(
        self, infer_type_request: "InferTypeRequest"
    ) -> "InferTypeResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_infer_type(
        self, stream: "grpclib.server.Stream[InferTypeRequest, InferTypeResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.infer_type(request)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/tierkreis.v1alpha.signature.TypeInference/InferType": grpclib.const.Handler(
                self.__rpc_infer_type,
                grpclib.const.Cardinality.UNARY_UNARY,
                InferTypeRequest,
                InferTypeResponse,
            ),
        }
