{% extends "service_stub.py.j2" %}

{# Class definition #}
{% block class_name %}{{ service.py_name }}{% if output_file.settings.client_generation.is_async_prefixed %}Async{% endif %}Stub{% endblock %}
{% block inherit_from %}betterproto2_grpclib.ServiceStub{% endblock %}

{# Methods definition #}
{% block method_definition %}
    async def {{ method.py_name }}(self
        {%- if not method.client_streaming -%}
            , message:
                {%- if method.is_input_msg_empty -%}
                    "{{ method.py_input_message_type }} | None" = None
                {%- else -%}
                    "{{ method.py_input_message_type }}"
                {%- endif -%}
        {%- else -%}
            {# Client streaming: need a request iterator instead #}
            , messages: "AsyncIterable[{{ method.py_input_message_type }}] | Iterable[{{ method.py_input_message_type }}]"
        {%- endif -%}
            ,
            *
            , timeout: "float | None" = None
            , deadline: "Deadline | None" = None
            , metadata: "MetadataLike | None" = None
            ) -> "{% if method.server_streaming %}AsyncIterator[{{ method.py_output_message_type }}]{% else %}{{ method.py_output_message_type }}{% endif %}":
{% endblock %}

{% block method_body %}
    {% if method.server_streaming %}
      {% if method.client_streaming %}
        async for response in self._stream_stream(
            "{{ method.route }}",
            messages,
            {{ method.py_input_message_type }},
            {{ method.py_output_message_type }},
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response
      {% else %}
        {% if method.is_input_msg_empty %}
        if message is None:
            message = {{ method.py_input_message_type }}()

        {% endif %}
        async for response in self._unary_stream(
            "{{ method.route }}",
            message,
            {{ method.py_output_message_type }},
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

      {% endif %}
    {% else %}
      {% if method.client_streaming %}
        return await self._stream_unary(
            "{{ method.route }}",
            messages,
            {{ method.py_input_message_type }},
            {{ method.py_output_message_type }},
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )
      {% else %}
        {% if method.is_input_msg_empty %}
        if message is None:
            message = {{ method.py_input_message_type }}()

        {% endif %}
        return await self._unary_unary(
            "{{ method.route }}",
            message,
            {{ method.py_output_message_type }},
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )
      {% endif %}
    {% endif %}
{% endblock %}