{%- import "struct_macros.tmpl" as struct_macros %}

{%- macro declare_params(prefix, parameters) %}
{%-   for param in parameters -%}
{{param.kind|cpp_wrapper_param_type}} {{prefix}}{{param.name}}
{%- if not loop.last %}, {% endif %}
{%-   endfor %}
{%- endmacro %}

{%- macro declare_callback(method, for_blink) -%}
base::OnceCallback<void(
{%-   for param in method.response_parameters -%}
{{param.kind|cpp_wrapper_param_type}}
{%-     if not loop.last %}, {% endif %}
{%-   endfor -%}
)>
{%- endmacro -%}

{%- macro declare_request_params(prefix, method) -%}
{{declare_params(prefix, method.parameters)}}
{%-   if method.response_parameters != None -%}
{%-     if method.parameters %}, {% endif -%}
{{method.name}}Callback callback
{%-   endif -%}
{%- endmacro -%}

{%- macro declare_sync_method_params(prefix, method) -%}
{{declare_params(prefix, method.parameters)}}
{%-   if method.response_parameters %}
{%-     if method.parameters %}, {% endif %}
{%-     for param in method.response_parameters -%}
{{param.kind|cpp_wrapper_call_type}}* out_{{prefix}}{{param.name}}
{%-       if not loop.last %}, {% endif %}
{%-     endfor %}
{%-   endif -%}
{%- endmacro -%}

{%- macro build_message_flags(is_response, is_sync_text, expects_response_text,
                              flags_name) %}
{%-   if is_response %}
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      (({{is_sync_text}}) ? mojo::Message::kFlagIsSync : 0);
{%-   else %}
  const uint32_t kFlags =
      (({{expects_response_text}}) ? mojo::Message::kFlagExpectsResponse : 0) |
      (({{is_sync_text}}) ? mojo::Message::kFlagIsSync : 0);
{%-   endif %}
{%- endmacro %}

{%- macro build_serialized_message(message_name, param_name_prefix,
                                   params_struct, params_description,
                                   flags_text, message_object_name) %}
  mojo::Message {{message_object_name}}(
      {{message_name}}, {{flags_text}}, 0, 0, nullptr);
  auto* buffer = {{message_object_name}}.payload_buffer();
  {{params_struct|get_qualified_name_for_kind(internal=True)}}::BufferWriter
      params;
  mojo::internal::SerializationContext serialization_context;
  {{struct_macros.serialize(params_struct, params_description,
                            param_name_prefix, "params", "buffer",
                            "&serialization_context")}}
  {{message_object_name}}.AttachHandlesFromSerializationContext(
      &serialization_context);
{%- endmacro %}

{%- macro define_message_type(interface, message_typename, message_name,
                              is_response, method, parameters, params_struct,
                              params_description) -%}
class {{message_typename}}
    : public mojo::internal::UnserializedMessageContext {
 public:
  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;

  explicit {{message_typename}}(
      uint32_t message_flags
{%-     for param in parameters %}
      , {{param.kind|cpp_wrapper_param_type}} param_{{param.name}}
{%-     endfor %}
  )
      : mojo::internal::UnserializedMessageContext(
          &kMessageTag,
          {{message_name}},
          message_flags)
{%-     for param in parameters -%}
{%-       if param.kind|is_interface_kind %}
      , param_{{param.name}}_(param_{{param.name}}.PassInterface())
{%-       else %}
      , param_{{param.name}}_(std::move(param_{{param.name}}))
{%-       endif %}
{%-     endfor -%} {}
  ~{{message_typename}}() override = default;

  static mojo::Message Build(
      bool serialize,
{%-   if not is_response %}
      bool expects_response,
{%-   endif %}
      bool is_sync
{%-   if parameters -%}
      ,
      {{declare_params("param_", parameters)}}
{%-   endif %}) {

    {{build_message_flags(is_response, "is_sync", "expects_response",
                          "kFlags")}}

    if (!serialize) {
      return mojo::Message(std::make_unique<{{message_typename}}>(
          kFlags
{%-     for param in parameters %}
          , std::move(param_{{param.name}})
{%-     endfor %}
          ));
    }

    DCHECK(serialize);
    {{build_serialized_message(message_name, "param_%s", params_struct,
                               params_description, "kFlags", "message")}}
    return message;
  }

{%      if not is_response %}
  void Dispatch({{interface.name}}* impl
{%-       if method.response_parameters != None -%}
      , {{interface.name}}::{{method.name}}Callback callback
{%-       endif -%}) {
    impl->{{method.name}}(
{%-       for param in parameters -%}
{%-         if param.kind|is_interface_kind %}
        {{param.kind|get_name_for_kind}}Ptr(std::move(param_{{param.name}}_))
{%-         else %}
        std::move(param_{{param.name}}_)
{%-         endif %}
        {%- if not loop.last -%}, {%- endif %}
{%-       endfor %}
{%-       if method.response_parameters != None %}
        {%- if parameters -%}, {% endif -%}std::move(callback)
{%-       endif -%});
  }
{%-     else %}
  void Dispatch({{interface.name}}::{{method.name}}Callback* callback) {
    std::move(*callback).Run(
{%-       for param in parameters -%}
{%-         if param.kind|is_interface_kind %}
        {{param.kind|get_name_for_kind}}Ptr(std::move(param_{{param.name}}_))
{%-         else %}
        std::move(param_{{param.name}}_)
{%-         endif %}
        {%- if not loop.last -%}, {% endif -%}
{%-       endfor -%});
  }

{%        if method.sync %}
  void HandleSyncResponse(
{%          for param in parameters %}
      {{param.kind|cpp_wrapper_call_type}}* out_{{param.name}}
      {%- if not loop.last -%}, {% endif -%}
{%-         endfor -%}) {
{%          for param in parameters -%}
{%-           if param.kind|is_interface_kind %}
    out_{{param.name}}->Bind(std::move(param_{{param.name}}_));
{%-           else %}
    *out_{{param.name}} = std::move(param_{{param.name}}_);
{%-           endif %}
{%          endfor %}
  }
{%-       endif -%}
{%-     endif %}

 private:
  // mojo::internal::UnserializedMessageContext:
  void Serialize(mojo::internal::SerializationContext* serialization_context,
                 mojo::internal::Buffer* buffer) override {
    {{params_struct|get_qualified_name_for_kind(internal=True)}}::BufferWriter
        params;
    {{struct_macros.serialize(params_struct, params_description, "param_%s_",
                              "params", "buffer", "serialization_context")}}
  }

{%-     for param in parameters %}
  {{param.kind|cpp_wrapper_type}} param_{{param.name}}_;
{%-     endfor %}

  DISALLOW_COPY_AND_ASSIGN({{message_typename}});
};

const mojo::internal::UnserializedMessageContext::Tag
{{message_typename}}::kMessageTag = {};
{%- endmacro -%}
