1{%- import "struct_macros.tmpl" as struct_macros %}
2
3{%- macro declare_params(prefix, parameters) %}
4{%-   for param in parameters -%}
5{{param.kind|cpp_wrapper_param_type}} {{prefix}}{{param.name}}
6{%- if not loop.last %}, {% endif %}
7{%-   endfor %}
8{%- endmacro %}
9
10{%- macro declare_callback(method, for_blink) -%}
11base::OnceCallback<void(
12{%-   for param in method.response_parameters -%}
13{{param.kind|cpp_wrapper_param_type}}
14{%-     if not loop.last %}, {% endif %}
15{%-   endfor -%}
16)>
17{%- endmacro -%}
18
19{%- macro declare_request_params(prefix, method) -%}
20{{declare_params(prefix, method.parameters)}}
21{%-   if method.response_parameters != None -%}
22{%-     if method.parameters %}, {% endif -%}
23{{method.name}}Callback callback
24{%-   endif -%}
25{%- endmacro -%}
26
27{%- macro trace_event(prefix, method_parameters, method_name, parameter_group,
28                      trace_event_type='', dereference_parameters=False) -%}
29{#- This macro assumes that the argument names are the ones declared by -#}
30{#- |declare_request_params/declare_sync_method_params|. Namely the |prefix| -#}
31{#- must be the same here as in -#}
32{#- |declare_request_params/declare_sync_method_params|. -#}
33{#- |trace_event_type| can be set to: -#}
34{#-   '' just standalone trace. -#}
35{#-     Parameter names must match |declare_request_params|. -#}
36{#-   '_BEGIN' input parameters to be later merged, must be before the _END. -#}
37{#-     Parameter names must match |declare_request_params|. -#}
38{#-   '_END' merge corresponding sync response parameters. -#}
39{#-     Parameter names must match |declare_sync_method_params|. -#}
40{#- |dereference_parameters| the parameters type is actually |kind*|. -#}
41{%-   if method_parameters -%}
42  TRACE_EVENT{{trace_event_type}}1(
43    "mojom", "{{method_name}}", "{{parameter_group}}",
44    [&](){
45      auto value = std::make_unique<base::trace_event::TracedValue>();
46      base::trace_event::TracedValue* raw_value = value.get();
47{%-     for param in method_parameters %}
48{%-       if dereference_parameters -%}
49{%-         set cpp_parameter_ptr = prefix + param.name %}
50{%-         set cpp_parameter_name = "(*%s)" % cpp_parameter_ptr %}
51      if ({{cpp_parameter_ptr}}) {
52{%-         for line in param.kind|write_input_param_for_tracing(
53                                     parameter_name=param.name,
54                                     cpp_parameter_name=cpp_parameter_name,
55                                     value='raw_value') %}
56        {{line}}
57{%-         endfor %}
58      } else {
59        raw_value->SetString("{{param.name}}", "nullptr");
60      }
61{%-       else %}  {#- if dereference_parameters #}
62{%-         for line in param.kind|write_input_param_for_tracing(
63                                     parameter_name=param.name,
64                                     cpp_parameter_name=prefix+param.name,
65                                     value='raw_value') %}
66      {{line}}
67{%-         endfor %}
68{%-       endif  %}  {#- if dereference_parameters #}
69{%-     endfor %}
70      return value;
71    }());
72{%-   else -%}  {#- if method_parameters -#}
73  TRACE_EVENT{{trace_event_type}}0("mojom", "{{method_name}}");
74{%-   endif %}  {#- if method_parameters #}
75{%- endmacro -%}
76
77{%- macro declare_sync_method_params(prefix, method) -%}
78{{declare_params(prefix, method.parameters)}}
79{%-   if method.response_parameters %}
80{%-     if method.parameters %}, {% endif %}
81{%-     for param in method.response_parameters -%}
82{{param.kind|cpp_wrapper_call_type}}* out_{{prefix}}{{param.name}}
83{%-       if not loop.last %}, {% endif %}
84{%-     endfor %}
85{%-   endif -%}
86{%- endmacro -%}
87
88{%- macro build_message_flags(is_response, is_sync_text, expects_response_text,
89                              flags_name) %}
90{%-   if is_response %}
91  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
92      (({{is_sync_text}}) ? mojo::Message::kFlagIsSync : 0);
93{%-   else %}
94  const uint32_t kFlags =
95      (({{expects_response_text}}) ? mojo::Message::kFlagExpectsResponse : 0) |
96      (({{is_sync_text}}) ? mojo::Message::kFlagIsSync : 0);
97{%-   endif %}
98{%- endmacro %}
99
100{%- macro build_serialized_message(message_name, method, param_name_prefix,
101                                   params_struct, params_description,
102                                   flags_text, message_object_name) %}
103{%-   if method.unlimited_message_size %}
104  mojo::Message {{message_object_name}}(
105      {{message_name}}, {{flags_text}}, 0, 0,
106      MOJO_CREATE_MESSAGE_FLAG_UNLIMITED_SIZE, nullptr);
107{%-   else %}
108  mojo::Message {{message_object_name}}(
109      {{message_name}}, {{flags_text}}, 0, 0, nullptr);
110{%-   endif %}
111  auto* buffer = {{message_object_name}}.payload_buffer();
112  {{params_struct|get_qualified_name_for_kind(internal=True)}}::BufferWriter
113      params;
114  mojo::internal::SerializationContext serialization_context;
115  {{struct_macros.serialize(params_struct, params_description,
116                            param_name_prefix, "params", "buffer",
117                            "&serialization_context")}}
118  {{message_object_name}}.AttachHandlesFromSerializationContext(
119      &serialization_context);
120{%- endmacro %}
121
122{%- macro define_message_type(interface, message_typename, message_name,
123                              is_response, method, parameters, params_struct,
124                              params_description) -%}
125class {{message_typename}}
126    : public mojo::internal::UnserializedMessageContext {
127 public:
128  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;
129
130  explicit {{message_typename}}(
131      uint32_t message_flags
132{%-     for param in parameters %}
133      , {{param.kind|cpp_wrapper_param_type}} param_{{param.name}}
134{%-     endfor %}
135  )
136      : mojo::internal::UnserializedMessageContext(
137          &kMessageTag,
138          {{message_name}},
139          message_flags)
140{%-     for param in parameters -%}
141{%-       if param.kind|is_interface_kind %}
142      , param_{{param.name}}_(param_{{param.name}}.PassInterface())
143{%-       else %}
144      , param_{{param.name}}_(std::move(param_{{param.name}}))
145{%-       endif %}
146{%-     endfor -%} {}
147  ~{{message_typename}}() override = default;
148
149  static mojo::Message Build(
150      bool serialize,
151{%-   if not is_response %}
152      bool expects_response,
153{%-   endif %}
154      bool is_sync
155{%-   if parameters -%}
156      ,
157      {{declare_params("param_", parameters)}}
158{%-   endif %}) {
159
160    {{build_message_flags(is_response, "is_sync", "expects_response",
161                          "kFlags")}}
162
163    if (!serialize) {
164      return mojo::Message(std::make_unique<{{message_typename}}>(
165          kFlags
166{%-     for param in parameters %}
167          , std::move(param_{{param.name}})
168{%-     endfor %}
169          ),
170{%-     if method.unlimited_message_size %}
171          MOJO_CREATE_MESSAGE_FLAG_UNLIMITED_SIZE);
172{%-     else %}
173          MOJO_CREATE_MESSAGE_FLAG_NONE);
174{%-     endif %}
175    }
176
177    DCHECK(serialize);
178    {{build_serialized_message(message_name, method, "param_%s", params_struct,
179                               params_description, "kFlags", "message")}}
180    return message;
181  }
182
183{%      if not is_response %}
184  void Dispatch(
185      mojo::Message* message,
186      {{interface.name}}* impl
187{%-       if method.response_parameters != None -%}
188      , {{interface.name}}::{{method.name}}Callback callback
189{%-       endif -%}) {
190    if (message->receiver_connection_group()) {
191{%-       for param in parameters -%}
192{%-         if param.kind|is_receiver_kind %}
193      param_{{param.name}}_.set_connection_group(
194          *message->receiver_connection_group());
195{%-         endif %}
196{%-       endfor %}
197    }
198
199    impl->{{method.name}}(
200{%-       for param in parameters -%}
201{%-         if param.kind|is_interface_kind %}
202        {{param.kind|get_name_for_kind}}Ptr(std::move(param_{{param.name}}_))
203{%-         else %}
204        std::move(param_{{param.name}}_)
205{%-         endif %}
206        {%- if not loop.last -%}, {%- endif %}
207{%-       endfor %}
208{%-       if method.response_parameters != None %}
209        {%- if parameters -%}, {% endif -%}std::move(callback)
210{%-       endif -%});
211  }
212{%-     else %}
213  void Dispatch(mojo::Message* message,
214                {{interface.name}}::{{method.name}}Callback* callback) {
215    if (message->receiver_connection_group()) {
216{%-       for param in parameters -%}
217{%-         if param.kind|is_receiver_kind %}
218      param_{{param.name}}_.set_connection_group(
219          *message->receiver_connection_group());
220{%-         endif %}
221{%-       endfor %}
222    }
223
224    std::move(*callback).Run(
225{%-       for param in parameters -%}
226{%-         if param.kind|is_interface_kind %}
227        {{param.kind|get_name_for_kind}}Ptr(std::move(param_{{param.name}}_))
228{%-         else %}
229        std::move(param_{{param.name}}_)
230{%-         endif %}
231        {%- if not loop.last -%}, {% endif -%}
232{%-       endfor -%});
233  }
234
235{%        if method.sync %}
236  void HandleSyncResponse(
237      mojo::Message* message
238{%          for param in parameters %},
239      {{param.kind|cpp_wrapper_call_type}}* out_{{param.name}}
240{%-         endfor -%}) {
241
242    if (message->receiver_connection_group()) {
243{%-       for param in parameters -%}
244{%-         if param.kind|is_receiver_kind %}
245      param_{{param.name}}_.set_connection_group(
246          *message->receiver_connection_group());
247{%-         endif %}
248{%-       endfor %}
249    }
250
251{%          for param in parameters -%}
252{%-           if param.kind|is_interface_kind %}
253    out_{{param.name}}->Bind(std::move(param_{{param.name}}_));
254{%-           else %}
255    *out_{{param.name}} = std::move(param_{{param.name}}_);
256{%-           endif %}
257{%          endfor %}
258  }
259{%-       endif -%}
260{%-     endif %}
261
262 private:
263  // mojo::internal::UnserializedMessageContext:
264  void Serialize(mojo::internal::SerializationContext* serialization_context,
265                 mojo::internal::Buffer* buffer) override {
266    {{params_struct|get_qualified_name_for_kind(internal=True)}}::BufferWriter
267        params;
268    {{struct_macros.serialize(params_struct, params_description, "param_%s_",
269                              "params", "buffer", "serialization_context")}}
270  }
271
272{%-     for param in parameters %}
273  {{param.kind|cpp_wrapper_type}} param_{{param.name}}_;
274{%-     endfor %}
275
276  DISALLOW_COPY_AND_ASSIGN({{message_typename}});
277};
278
279const mojo::internal::UnserializedMessageContext::Tag
280{{message_typename}}::kMessageTag = {};
281{%- endmacro -%}
282