chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl

{%- 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 trace_event(prefix, method_parameters, method_name, parameter_group,
                      trace_event_type='', dereference_parameters=False) -%}
{#- This macro assumes that the argument names are the ones declared by -#}
{#- |declare_request_params/declare_sync_method_params|. Namely the |prefix| -#}
{#- must be the same here as in -#}
{#- |declare_request_params/declare_sync_method_params|. -#}
{#- |trace_event_type| can be set to: -#}
{#-   '' just standalone trace. -#}
{#-     Parameter names must match |declare_request_params|. -#}
{#-   '_BEGIN' input parameters to be later merged, must be before the _END. -#}
{#-     Parameter names must match |declare_request_params|. -#}
{#-   '_END' merge corresponding sync response parameters. -#}
{#-     Parameter names must match |declare_sync_method_params|. -#}
{#- |dereference_parameters| the parameters type is actually |kind*|. -#}
{%-   if method_parameters -%}
  TRACE_EVENT{{trace_event_type}}1(
    "mojom", "{{method_name}}", "{{parameter_group}}",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
{%-     for param in method_parameters %}
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("{{param.name}}"), {{prefix+param.name}},
                        "<value of type {{param.kind|cpp_wrapper_param_type}}>");
{%-     endfor %}
   });
{%-   else -%}  {#- if method_parameters -#}
  TRACE_EVENT{{trace_event_type}}0("mojom", "{{method_name}}");
{%-   endif %}  {#- if method_parameters #}
{%- 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, allow_interrupt_text,
                              is_urgent_text, expects_response_text, flags_name) %}
{%-   if is_response %}
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      (({{is_sync_text}}) ? mojo::Message::kFlagIsSync : 0) |
      (({{allow_interrupt_text}}) ? 0 : mojo::Message::kFlagNoInterrupt) |
      (({{is_urgent_text}}) ? mojo::Message::kFlagIsUrgent : 0);
{%-   else %}
  const uint32_t kFlags =
      (({{expects_response_text}}) ? mojo::Message::kFlagExpectsResponse : 0) |
      (({{is_sync_text}}) ? mojo::Message::kFlagIsSync : 0) |
      (({{allow_interrupt_text}}) ? 0 : mojo::Message::kFlagNoInterrupt) |
      (({{is_urgent_text}}) ? mojo::Message::kFlagIsUrgent : 0);
{%-   endif %}
{%- endmacro %}

{%- macro build_serialized_message(message_name, method, param_name_prefix,
                                   params_struct, params_description,
                                   flags_text, message_object_name,
                                   has_size_estimator = False) %}
  const size_t estimated_payload_size =
{%-   if has_size_estimator and method.estimate_message_size  %}
    size_estimator_.EstimatePayloadSize({{message_name}});
{%-   else %}
    0;
{%-   endif %}

{%-   if method.unlimited_message_size %}
  mojo::Message {{message_object_name}}(
      {{message_name}}, {{flags_text}},
      MOJO_CREATE_MESSAGE_FLAG_UNLIMITED_SIZE,
      estimated_payload_size);
{%-   else %}
  mojo::Message {{message_object_name}}(
      {{message_name}}, {{flags_text}}, estimated_payload_size);
{%-   endif %}
  mojo::internal::MessageFragment<
      {{params_struct|get_qualified_name_for_kind(internal=True)}}> params(
          {{message_object_name}});
  {{struct_macros.serialize(
      params_struct, params_description, param_name_prefix, "params")}}
{%- 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}}(const {{message_typename}}&) = delete;
  {{message_typename}}& operator=(const {{message_typename}}&) = delete;

  ~{{message_typename}}() override = default;

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

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

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

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

{%      if not is_response %}
  void Dispatch(
      mojo::Message* message,
      {{interface.name}}* impl
{%-       if method.response_parameters != None -%}
      , {{interface.name}}::{{method.name}}Callback callback
{%-       endif -%}) {
    if (message->receiver_connection_group()) {
{%-       for param in parameters -%}
{%-         if param.kind|is_receiver_kind %}
      param_{{param.name}}_.set_connection_group(
          *message->receiver_connection_group());
{%-         endif %}
{%-       endfor %}
    }

    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(mojo::Message* message,
                {{interface.name}}::{{method.name}}Callback* callback) {
    if (message->receiver_connection_group()) {
{%-       for param in parameters -%}
{%-         if param.kind|is_receiver_kind %}
      param_{{param.name}}_.set_connection_group(
          *message->receiver_connection_group());
{%-         endif %}
{%-       endfor %}
    }

    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(
      mojo::Message* message
{%          for param in parameters %},
      {{param.kind|cpp_wrapper_call_type}}* out_{{param.name}}
{%-         endfor -%}) {

    if (message->receiver_connection_group()) {
{%-       for param in parameters -%}
{%-         if param.kind|is_receiver_kind %}
      param_{{param.name}}_.set_connection_group(
          *message->receiver_connection_group());
{%-         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::Message& message) override {
    mojo::internal::MessageFragment<
        {{params_struct|get_qualified_name_for_kind(internal=True)}}> params(
            message);
    {{struct_macros.serialize(
        params_struct, params_description, "param_%s_", "params")}}
  }

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

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