{#- Template for expressions.

This template renders a Griffe expression,
which is a tree-like structure representing a Python expression.
-#}

{% block logs scoped %}
  {#- Logging block.

  This block can be used to log debug messages, deprecation messages, warnings, etc.
  -#}
{% endblock logs %}

{%- macro crossref(name, annotation_path, backlink_type="") -%}
  {#- Output a cross-reference.

  This macro outputs a cross-reference to the given name.

  Parameters:
      name (griffe.ExprName): The name to cross-reference.
      annotation_path (str): Either "brief", "source", or "full".

  Returns:
      Either a cross-reference (using an autoref element) or the name itself.
  -#}
  {%- with full = name.canonical_path -%}
    {%- if annotation_path == "brief" -%}
      {%- set annotation = name.canonical_name -%}
    {%- elif annotation_path == "source" -%}
      {%- set annotation = name.name -%}
    {%- elif annotation_path == "full" -%}
      {%- set annotation = full -%}
    {%- endif -%}
    {%- for prefix, title, path, suffix in annotation|split_path(full) -%}
      {{ prefix }}
      {%- if not signature -%}
        {#- Always render cross-references outside of signatures. We don't need to stash them. -#}
        <autoref identifier="{{ path }}"{% if backlink_type %} backlink-type="{{ backlink_type }}" backlink-anchor="{{ html_id }}"{% endif %} optional{% if title != path %} hover{% endif %}>{{ title }}</autoref>
      {%- elif config.signature_crossrefs -%}
        {#- We're in a signature and cross-references are enabled, we must render one and stash it. -#}
        {%- filter stash_crossref(length=title|length) -%}
          <autoref identifier="{{ path }}"{% if backlink_type %} backlink-type="{{ backlink_type }}" backlink-anchor="{{ html_id }}"{% endif %} optional{% if title != path %} hover{% endif %}>{{ title }}</autoref>
        {%- endfilter -%}
      {%- else -%}
        {#- We're in a signature but cross-references are disabled, we just render the title. -#}
        {{ title }}
      {%- endif -%}
      {{ suffix }}
    {%- endfor -%}
  {%- endwith -%}
{%- endmacro -%}

{%- macro param_crossref(expression) -%}
  {#- Render a cross-reference to a parameter heading.

  Parameters:
      expression (griffe.expressions.Expr): The expression to render.

  Returns:
      The autorefs cross-reference, or the parameter name.
  -#}
  {%- if config.signature_crossrefs -%}
    {%- if signature -%}
      {%- filter stash_crossref(length=expression.name|length) -%}
        <autoref identifier="{{ expression.canonical_path }}" optional hover>{{ expression.name }}</autoref>
      {%- endfilter -%}
    {%- else -%}
      <autoref identifier="{{ expression.canonical_path }}" optional hover>{{ expression.name }}</autoref>
    {%- endif -%}
  {%- else -%}
    {{ expression.name }}
  {%- endif -%}
{%- endmacro -%}

{%- macro render(expression, annotations_path, backlink_type="") -%}
  {#- Render an expression.

  Parameters:
      expression (griffe.Expr): The expression to render.
      annotations_path (str): Either "brief", "source", or "full".

  Returns:
      The rendered expression.
  -#}
  {%- if expression is string -%}
    {%- if signature -%}{{ expression|safe }}{%- else -%}{{ expression }}{%- endif -%}
  {%- elif expression.classname == "ExprName" -%}
    {{ crossref(expression, annotations_path, backlink_type) }}
  {%- elif config.unwrap_annotated and expression.classname == "ExprSubscript" and expression.canonical_path in ("typing.Annotated", "typing_extensions.Annotated") -%}
    {{ render(expression.slice.elements[0], annotations_path) }}
  {%- elif expression.classname == "ExprAttribute" -%}
    {%- if annotations_path == "brief" -%}
      {%- if expression.last.is_enum_value -%}
        {{ crossref(expression.last.parent, "brief", backlink_type) }}.value
      {%- else -%}
        {{ render(expression.last, "brief") }}
      {%- endif -%}
    {%- elif annotations_path == "full" -%}
      {{ render(expression.first, "full") }}
      {%- for element in expression -%}
        {%- if not loop.first -%}
          {{ render(element, "brief") }}
        {%- endif -%}
      {%- endfor -%}
    {%- else -%}
      {%- for element in expression -%}
        {{ render(element, annotations_path) }}
      {%- endfor -%}
    {%- endif -%}
  {%- elif expression.classname == "ExprKeyword" -%}
    {{ param_crossref(expression) }}={{ render(expression.value, annotations_path) }}
  {%- else -%}
    {%- for element in expression -%}
      {{ render(element, annotations_path) }}
    {%- endfor -%}
  {%- endif -%}
{%- endmacro -%}

{{ render(expression, config.annotations_path, backlink_type|default("")) }}
