Remove std::chrono completely
[WebKit.git] / Source / WebKit / Scripts / webkit / messages.py
1 # Copyright (C) 2010-2017 Apple Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1.  Redistributions of source code must retain the above copyright
7 #     notice, this list of conditions and the following disclaimer.
8 # 2.  Redistributions in binary form must reproduce the above copyright
9 #     notice, this list of conditions and the following disclaimer in the
10 #     documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
23 import collections
24 import re
25 import sys
26
27 from webkit import parser
28
29 WANTS_CONNECTION_ATTRIBUTE = 'WantsConnection'
30 LEGACY_RECEIVER_ATTRIBUTE = 'LegacyReceiver'
31 DELAYED_ATTRIBUTE = 'Delayed'
32
33 _license_header = """/*
34  * Copyright (C) 2010 Apple Inc. All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1.  Redistributions of source code must retain the above copyright
40  *     notice, this list of conditions and the following disclaimer.
41  * 2.  Redistributions in binary form must reproduce the above copyright
42  *     notice, this list of conditions and the following disclaimer in the
43  *     documentation and/or other materials provided with the distribution.
44  *
45  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
49  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
52  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
54  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55  */
56
57 """
58
59
60 def messages_header_filename(receiver):
61     return '%sMessages.h' % receiver.name
62
63
64 def surround_in_condition(string, condition):
65     if not condition:
66         return string
67     return '#if %s\n%s#endif\n' % (condition, string)
68
69
70 def function_parameter_type(type, kind):
71     # Don't use references for built-in types.
72     builtin_types = frozenset([
73         'bool',
74         'float',
75         'double',
76         'uint8_t',
77         'uint16_t',
78         'uint32_t',
79         'uint64_t',
80         'int8_t',
81         'int16_t',
82         'int32_t',
83         'int64_t',
84     ])
85
86     if type in builtin_types:
87         return type
88
89     if kind == 'enum':
90         return type
91
92     return 'const %s&' % type
93
94
95 def reply_parameter_type(type):
96     return '%s&' % type
97
98
99 def arguments_type(message):
100     return 'std::tuple<%s>' % ', '.join(function_parameter_type(parameter.type, parameter.kind) for parameter in message.parameters)
101
102
103 def reply_type(message):
104     return 'std::tuple<%s>' % (', '.join(reply_parameter_type(parameter.type) for parameter in message.reply_parameters))
105
106
107 def message_to_struct_declaration(message):
108     result = []
109     function_parameters = [(function_parameter_type(x.type, x.kind), x.name) for x in message.parameters]
110     result.append('class %s {\n' % message.name)
111     result.append('public:\n')
112     result.append('    typedef %s Arguments;\n' % arguments_type(message))
113     result.append('\n')
114     result.append('    static IPC::StringReference receiverName() { return messageReceiverName(); }\n')
115     result.append('    static IPC::StringReference name() { return IPC::StringReference("%s"); }\n' % message.name)
116     result.append('    static const bool isSync = %s;\n' % ('false', 'true')[message.reply_parameters != None])
117     result.append('\n')
118     if message.reply_parameters != None:
119         if message.has_attribute(DELAYED_ATTRIBUTE):
120             send_parameters = [(function_parameter_type(x.type, x.kind), x.name) for x in message.reply_parameters]
121             result.append('    struct DelayedReply : public ThreadSafeRefCounted<DelayedReply> {\n')
122             result.append('        DelayedReply(Ref<IPC::Connection>&&, std::unique_ptr<IPC::Encoder>);\n')
123             result.append('        ~DelayedReply();\n')
124             result.append('\n')
125             result.append('        bool send(%s);\n' % ', '.join([' '.join(x) for x in send_parameters]))
126             result.append('\n')
127             result.append('    private:\n')
128             result.append('        RefPtr<IPC::Connection> m_connection;\n')
129             result.append('        std::unique_ptr<IPC::Encoder> m_encoder;\n')
130             result.append('    };\n\n')
131
132         result.append('    typedef %s Reply;\n' % reply_type(message))
133
134     if len(function_parameters):
135         result.append('    %s%s(%s)' % (len(function_parameters) == 1 and 'explicit ' or '', message.name, ', '.join([' '.join(x) for x in function_parameters])))
136         result.append('\n        : m_arguments(%s)\n' % ', '.join([x[1] for x in function_parameters]))
137         result.append('    {\n')
138         result.append('    }\n\n')
139     result.append('    const Arguments& arguments() const\n')
140     result.append('    {\n')
141     result.append('        return m_arguments;\n')
142     result.append('    }\n')
143     result.append('\n')
144     result.append('private:\n')
145     result.append('    Arguments m_arguments;\n')
146     result.append('};\n')
147     return surround_in_condition(''.join(result), message.condition)
148
149
150 def forward_declaration(namespace, kind_and_type):
151     kind, type = kind_and_type
152
153     qualified_name = '%s::%s' % (namespace, type)
154     if kind == 'struct':
155         return 'struct %s' % type
156     elif kind == 'enum':
157         return 'enum class %s' % type
158     else:
159         return 'class %s' % type
160
161
162 def forward_declarations_for_namespace(namespace, kind_and_types):
163     result = []
164     result.append('namespace %s {\n' % namespace)
165     result += ['    %s;\n' % forward_declaration(namespace, x) for x in kind_and_types]
166     result.append('}\n')
167     return ''.join(result)
168
169
170 def forward_declarations_and_headers(receiver):
171     types_by_namespace = collections.defaultdict(set)
172
173     headers = set([
174         '"ArgumentCoders.h"',
175     ])
176
177     non_template_wtf_types = frozenset([
178         'String',
179     ])
180
181     for message in receiver.messages:
182         if message.reply_parameters != None and message.has_attribute(DELAYED_ATTRIBUTE):
183             headers.add('<wtf/ThreadSafeRefCounted.h>')
184             types_by_namespace['IPC'].update([('class', 'Connection')])
185
186     no_forward_declaration_types = frozenset([
187         'WebCore::DocumentIdentifier',
188         'WebCore::ServiceWorkerIdentifier',
189         'WebCore::ServiceWorkerOrClientData',
190         'WebCore::ServiceWorkerOrClientIdentifier',
191         'WebCore::ServiceWorkerRegistrationIdentifier',
192         'WebCore::SWServerConnectionIdentifier',
193     ])
194
195     for parameter in receiver.iterparameters():
196         kind = parameter.kind
197         type = parameter.type
198
199         if type.find('<') != -1 or type in no_forward_declaration_types:
200             # Don't forward declare class templates.
201             headers.update(headers_for_type(type))
202             continue
203
204         split = type.split('::')
205
206         # Handle WTF types even if the WTF:: prefix is not given
207         if split[0] in non_template_wtf_types:
208             split.insert(0, 'WTF')
209
210         if len(split) == 2:
211             namespace = split[0]
212             inner_type = split[1]
213             types_by_namespace[namespace].add((kind, inner_type))
214         elif len(split) > 2:
215             # We probably have a nested struct, which means we can't forward declare it.
216             # Include its header instead.
217             headers.update(headers_for_type(type))
218
219     forward_declarations = '\n'.join([forward_declarations_for_namespace(namespace, types) for (namespace, types) in sorted(types_by_namespace.items())])
220     headers = ['#include %s\n' % header for header in sorted(headers)]
221
222     return (forward_declarations, headers)
223
224
225 def generate_messages_header(file):
226     receiver = parser.parse(file)
227
228     result = []
229
230     result.append(_license_header)
231
232     result.append('#pragma once\n')
233     result.append('\n')
234
235     if receiver.condition:
236         result.append('#if %s\n\n' % receiver.condition)
237
238     forward_declarations, headers = forward_declarations_and_headers(receiver)
239
240     result += headers
241     result.append('\n')
242
243     result.append(forward_declarations)
244     result.append('\n')
245
246     result.append('namespace Messages {\nnamespace %s {\n' % receiver.name)
247     result.append('\n')
248     result.append('static inline IPC::StringReference messageReceiverName()\n')
249     result.append('{\n')
250     result.append('    return IPC::StringReference("%s");\n' % receiver.name)
251     result.append('}\n')
252     result.append('\n')
253     result.append('\n'.join([message_to_struct_declaration(x) for x in receiver.messages]))
254     result.append('\n')
255     result.append('} // namespace %s\n} // namespace Messages\n' % receiver.name)
256
257     if receiver.condition:
258         result.append('\n#endif // %s\n' % receiver.condition)
259
260     return ''.join(result)
261
262
263 def handler_function(receiver, message):
264     if message.name.find('URL') == 0:
265         return '%s::%s' % (receiver.name, 'url' + message.name[3:])
266     return '%s::%s' % (receiver.name, message.name[0].lower() + message.name[1:])
267
268
269 def async_message_statement(receiver, message):
270     dispatch_function_args = ['decoder', 'this', '&%s' % handler_function(receiver, message)]
271
272     dispatch_function = 'handleMessage'
273
274     if message.has_attribute(WANTS_CONNECTION_ATTRIBUTE):
275         dispatch_function_args.insert(0, 'connection')
276
277     result = []
278     result.append('    if (decoder.messageName() == Messages::%s::%s::name()) {\n' % (receiver.name, message.name))
279     result.append('        IPC::%s<Messages::%s::%s>(%s);\n' % (dispatch_function, receiver.name, message.name, ', '.join(dispatch_function_args)))
280     result.append('        return;\n')
281     result.append('    }\n')
282     return surround_in_condition(''.join(result), message.condition)
283
284
285 def sync_message_statement(receiver, message):
286     dispatch_function = 'handleMessage'
287     if message.has_attribute(DELAYED_ATTRIBUTE):
288         dispatch_function += 'Delayed'
289
290     wants_connection = message.has_attribute(DELAYED_ATTRIBUTE) or message.has_attribute(WANTS_CONNECTION_ATTRIBUTE)
291
292     result = []
293     result.append('    if (decoder.messageName() == Messages::%s::%s::name()) {\n' % (receiver.name, message.name))
294     result.append('        IPC::%s<Messages::%s::%s>(%sdecoder, %sreplyEncoder, this, &%s);\n' % (dispatch_function, receiver.name, message.name, 'connection, ' if wants_connection else '', '' if message.has_attribute(DELAYED_ATTRIBUTE) else '*', handler_function(receiver, message)))
295     result.append('        return;\n')
296     result.append('    }\n')
297     return surround_in_condition(''.join(result), message.condition)
298
299
300 def class_template_headers(template_string):
301     template_string = template_string.strip()
302
303     class_template_types = {
304         'WebCore::RectEdges': {'headers': ['<WebCore/RectEdges.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
305         'HashMap': {'headers': ['<wtf/HashMap.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
306         'HashSet': {'headers': ['<wtf/HashSet.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
307         'std::optional': {'headers': ['<wtf/Optional.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
308         'OptionSet': {'headers': ['<wtf/OptionSet.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
309         'Vector': {'headers': ['<wtf/Vector.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
310         'std::pair': {'headers': ['<utility>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
311     }
312
313     match = re.match('(?P<template_name>.+?)<(?P<parameter_string>.+)>', template_string)
314     if not match:
315         return {'header_infos': [], 'types': [template_string]}
316
317     template_name = match.groupdict()['template_name']
318     if template_name not in class_template_types:
319         sys.stderr.write("Error: no class template type is defined for '%s'\n" % (template_string))
320         sys.exit(1)
321
322     header_infos = [class_template_types[template_name]]
323     types = []
324
325     for parameter in parser.split_parameters_string(match.groupdict()['parameter_string']):
326         parameter_header_infos_and_types = class_template_headers(parameter)
327
328         header_infos += parameter_header_infos_and_types['header_infos']
329         types += parameter_header_infos_and_types['types']
330
331     return {'header_infos': header_infos, 'types': types}
332
333
334 def argument_coder_headers_for_type(type):
335     header_infos_and_types = class_template_headers(type)
336
337     special_cases = {
338         'String': '"ArgumentCoders.h"',
339         'WebKit::ScriptMessageHandlerHandle': '"WebScriptMessageHandler.h"',
340     }
341
342     headers = []
343     for header_info in header_infos_and_types['header_infos']:
344         headers += header_info['argument_coder_headers']
345
346     for type in header_infos_and_types['types']:
347         if type in special_cases:
348             headers.append(special_cases[type])
349             continue
350
351         split = type.split('::')
352         if len(split) < 2:
353             continue
354         if split[0] == 'WebCore':
355             headers.append('"WebCoreArgumentCoders.h"')
356
357     return headers
358
359
360 def headers_for_type(type):
361     header_infos_and_types = class_template_headers(type)
362
363     special_cases = {
364         'MonotonicTime': ['<wtf/MonotonicTime.h>'],
365         'Seconds': ['<wtf/Seconds.h>'],
366         'WallTime': ['<wtf/WallTime.h>'],
367         'String': ['<wtf/text/WTFString.h>'],
368         'PAL::SessionID': ['<pal/SessionID.h>'],
369         'WebCore::AttachmentDisplayOptions': ['<WebCore/AttachmentTypes.h>'],
370         'WebCore::AutoplayEventFlags': ['<WebCore/AutoplayEvent.h>'],
371         'WebCore::ExceptionDetails': ['<WebCore/JSDOMExceptionHandling.h>'],
372         'WebCore::FileChooserSettings': ['<WebCore/FileChooser.h>'],
373         'WebCore::GrammarDetail': ['<WebCore/TextCheckerClient.h>'],
374         'WebCore::HasInsecureContent': ['<WebCore/FrameLoaderTypes.h>'],
375         'WebCore::Highlight': ['<WebCore/InspectorOverlay.h>'],
376         'WebCore::IncludeSecureCookies': ['<WebCore/CookiesStrategy.h>'],
377         'WebCore::KeyframeValueList': ['<WebCore/GraphicsLayer.h>'],
378         'WebCore::KeypressCommand': ['<WebCore/KeyboardEvent.h>'],
379         'WebCore::MediaConstraints': ['<WebCore/MediaConstraints.h>'],
380         'WebCore::PasteboardCustomData': ['<WebCore/Pasteboard.h>'],
381         'WebCore::PasteboardImage': ['<WebCore/Pasteboard.h>'],
382         'WebCore::PasteboardURL': ['<WebCore/Pasteboard.h>'],
383         'WebCore::PasteboardWebContent': ['<WebCore/Pasteboard.h>'],
384         'WebCore::PaymentAuthorizationResult': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
385         'WebCore::PaymentMethodUpdate': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
386         'WebCore::PluginInfo': ['<WebCore/PluginData.h>'],
387         'WebCore::PolicyAction': ['<WebCore/FrameLoaderTypes.h>'],
388         'WebCore::RecentSearch': ['<WebCore/SearchPopupMenu.h>'],
389         'WebCore::SWServerConnectionIdentifier': ['<WebCore/ServiceWorkerTypes.h>'],
390         'WebCore::ServiceWorkerOrClientData': ['<WebCore/ServiceWorkerTypes.h>', '<WebCore/ServiceWorkerClientData.h>', '<WebCore/ServiceWorkerData.h>'],
391         'WebCore::ServiceWorkerOrClientIdentifier': ['<WebCore/ServiceWorkerTypes.h>', '<WebCore/ServiceWorkerClientIdentifier.h>'],
392         'WebCore::ServiceWorkerRegistrationIdentifier': ['<WebCore/ServiceWorkerTypes.h>'],
393         'WebCore::ServiceWorkerRegistrationState': ['<WebCore/ServiceWorkerTypes.h>'],
394         'WebCore::ServiceWorkerState': ['<WebCore/ServiceWorkerTypes.h>'],
395         'WebCore::ShippingContactUpdate': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
396         'WebCore::ShippingMethodUpdate': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
397         'WebCore::ShouldNotifyWhenResolved': ['<WebCore/ServiceWorkerTypes.h>'],
398         'WebCore::ShouldSample': ['<WebCore/DiagnosticLoggingClient.h>'],
399         'WebCore::TextCheckingRequestData': ['<WebCore/TextChecking.h>'],
400         'WebCore::TextCheckingResult': ['<WebCore/TextCheckerClient.h>'],
401         'WebCore::TextIndicatorData': ['<WebCore/TextIndicator.h>'],
402         'WebCore::TextureMapperAnimations': ['<WebCore/TextureMapperAnimation.h>'],
403         'WebCore::ViewportAttributes': ['<WebCore/ViewportArguments.h>'],
404         'WebCore::SelectionRect': ['"EditorState.h"'],
405         'WebKit::BackForwardListItemState': ['"SessionState.h"'],
406         'WebKit::LayerHostingMode': ['"LayerTreeContext.h"'],
407         'WebKit::PageState': ['"SessionState.h"'],
408         'WebKit::WebGestureEvent': ['"WebEvent.h"'],
409         'WebKit::WebKeyboardEvent': ['"WebEvent.h"'],
410         'WebKit::WebMouseEvent': ['"WebEvent.h"'],
411         'WebKit::WebTouchEvent': ['"WebEvent.h"'],
412         'WebKit::WebWheelEvent': ['"WebEvent.h"'],
413         'struct WebKit::WebUserScriptData': ['"WebUserContentControllerDataTypes.h"'],
414         'struct WebKit::WebUserStyleSheetData': ['"WebUserContentControllerDataTypes.h"'],
415         'struct WebKit::WebScriptMessageHandlerData': ['"WebUserContentControllerDataTypes.h"'],
416     }
417
418     headers = []
419     for header_info in header_infos_and_types['header_infos']:
420         headers += header_info['headers']
421
422     for type in header_infos_and_types['types']:
423         if type in special_cases:
424             headers += special_cases[type]
425             continue
426
427         # We assume that we must include a header for a type iff it has a scope
428         # resolution operator (::).
429         split = type.split('::')
430         if len(split) < 2:
431             continue
432
433         if split[0] == 'WebKit' or split[0] == 'IPC':
434             headers.append('"%s.h"' % split[1])
435         else:
436             headers.append('<%s/%s.h>' % tuple(split[0:2]))
437
438     return headers
439
440
441 def generate_message_handler(file):
442     receiver = parser.parse(file)
443     header_conditions = {
444         '"%s"' % messages_header_filename(receiver): [None],
445         '"HandleMessage.h"': [None],
446         '"Decoder.h"': [None],
447     }
448
449     type_conditions = {}
450     for parameter in receiver.iterparameters():
451         if not parameter.type in type_conditions:
452             type_conditions[parameter.type] = []
453
454         if not parameter.condition in type_conditions[parameter.type]:
455             type_conditions[parameter.type].append(parameter.condition)
456
457     for parameter in receiver.iterparameters():
458         type = parameter.type
459         conditions = type_conditions[type]
460
461         argument_encoder_headers = argument_coder_headers_for_type(type)
462         if argument_encoder_headers:
463             for header in argument_encoder_headers:
464                 if header not in header_conditions:
465                     header_conditions[header] = []
466                 header_conditions[header].extend(conditions)
467
468         type_headers = headers_for_type(type)
469         for header in type_headers:
470             if header not in header_conditions:
471                 header_conditions[header] = []
472             header_conditions[header].extend(conditions)
473
474     for message in receiver.messages:
475         if message.reply_parameters is not None:
476             for reply_parameter in message.reply_parameters:
477                 type = reply_parameter.type
478                 argument_encoder_headers = argument_coder_headers_for_type(type)
479                 if argument_encoder_headers:
480                     for header in argument_encoder_headers:
481                         if header not in header_conditions:
482                             header_conditions[header] = []
483                         header_conditions[header].append(message.condition)
484
485                 type_headers = headers_for_type(type)
486                 for header in type_headers:
487                     if header not in header_conditions:
488                         header_conditions[header] = []
489                     header_conditions[header].append(message.condition)
490
491     result = []
492
493     result.append(_license_header)
494     result.append('#include "config.h"\n')
495     result.append('\n')
496
497     if receiver.condition:
498         result.append('#if %s\n\n' % receiver.condition)
499
500     result.append('#include "%s.h"\n\n' % receiver.name)
501     for header in sorted(header_conditions):
502         if header_conditions[header] and not None in header_conditions[header]:
503             result.append('#if %s\n' % ' || '.join(set(header_conditions[header])))
504             result += ['#include %s\n' % header]
505             result.append('#endif\n')
506         else:
507             result += ['#include %s\n' % header]
508     result.append('\n')
509
510     sync_delayed_messages = []
511     for message in receiver.messages:
512         if message.reply_parameters != None and message.has_attribute(DELAYED_ATTRIBUTE):
513             sync_delayed_messages.append(message)
514
515     if sync_delayed_messages:
516         result.append('namespace Messages {\n\nnamespace %s {\n\n' % receiver.name)
517
518         for message in sync_delayed_messages:
519             send_parameters = [(function_parameter_type(x.type, x.kind), x.name) for x in message.reply_parameters]
520
521             if message.condition:
522                 result.append('#if %s\n\n' % message.condition)
523
524             result.append('%s::DelayedReply::DelayedReply(Ref<IPC::Connection>&& connection, std::unique_ptr<IPC::Encoder> encoder)\n' % message.name)
525             result.append('    : m_connection(WTFMove(connection))\n')
526             result.append('    , m_encoder(WTFMove(encoder))\n')
527             result.append('{\n')
528             result.append('}\n')
529             result.append('\n')
530             result.append('%s::DelayedReply::~DelayedReply()\n' % message.name)
531             result.append('{\n')
532             result.append('    ASSERT(!m_connection);\n')
533             result.append('}\n')
534             result.append('\n')
535             result.append('bool %s::DelayedReply::send(%s)\n' % (message.name, ', '.join([' '.join(x) for x in send_parameters])))
536             result.append('{\n')
537             result.append('    ASSERT(m_encoder);\n')
538             result += ['    *m_encoder << %s;\n' % x.name for x in message.reply_parameters]
539             result.append('    bool _result = m_connection->sendSyncReply(WTFMove(m_encoder));\n')
540             result.append('    m_connection = nullptr;\n')
541             result.append('    return _result;\n')
542             result.append('}\n')
543             result.append('\n')
544
545             if message.condition:
546                 result.append('#endif\n\n')
547
548         result.append('} // namespace %s\n\n} // namespace Messages\n\n' % receiver.name)
549
550     result.append('namespace WebKit {\n\n')
551
552     async_messages = []
553     sync_messages = []
554     for message in receiver.messages:
555         if message.reply_parameters is not None:
556             sync_messages.append(message)
557         else:
558             async_messages.append(message)
559
560     if async_messages:
561         result.append('void %s::didReceive%sMessage(IPC::Connection& connection, IPC::Decoder& decoder)\n' % (receiver.name, receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else ''))
562         result.append('{\n')
563         result += [async_message_statement(receiver, message) for message in async_messages]
564         if (receiver.superclass):
565             result.append('    %s::didReceiveMessage(connection, decoder);\n' % (receiver.superclass))
566         else:
567             result.append('    UNUSED_PARAM(connection);\n')
568             result.append('    UNUSED_PARAM(decoder);\n')
569             result.append('    ASSERT_NOT_REACHED();\n')
570         result.append('}\n')
571
572     if sync_messages:
573         result.append('\n')
574         result.append('void %s::didReceiveSync%sMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)\n' % (receiver.name, receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else ''))
575         result.append('{\n')
576         result += [sync_message_statement(receiver, message) for message in sync_messages]
577         result.append('    UNUSED_PARAM(connection);\n')
578         result.append('    UNUSED_PARAM(decoder);\n')
579         result.append('    UNUSED_PARAM(replyEncoder);\n')
580         result.append('    ASSERT_NOT_REACHED();\n')
581         result.append('}\n')
582
583     result.append('\n} // namespace WebKit\n')
584
585     if receiver.condition:
586         result.append('\n#endif // %s\n' % receiver.condition)
587
588     return ''.join(result)