Replace uses of ArgumentEncoder/ArgumentDecoder with MessageEncoder/MessageDecoder
[WebKit-https.git] / Source / WebKit2 / Scripts / webkit2 / messages.py
1 # Copyright (C) 2010, 2011 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 from webkit2 import parser
26
27 DELAYED_ATTRIBUTE = 'Delayed'
28 DISPATCH_ON_CONNECTION_QUEUE_ATTRIBUTE = 'DispatchOnConnectionQueue'
29 VARIADIC_ATTRIBUTE = 'Variadic'
30
31 _license_header = """/*
32  * Copyright (C) 2010 Apple Inc. All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions
36  * are met:
37  * 1.  Redistributions of source code must retain the above copyright
38  *     notice, this list of conditions and the following disclaimer.
39  * 2.  Redistributions in binary form must reproduce the above copyright
40  *     notice, this list of conditions and the following disclaimer in the
41  *     documentation and/or other materials provided with the distribution.
42  *
43  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
44  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
47  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
49  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
50  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
51  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53  */
54
55 """
56
57
58 def messages_header_filename(receiver):
59     return '%sMessages.h' % receiver.name
60
61
62 def surround_in_condition(string, condition):
63     if not condition:
64         return string
65     return '#if %s\n%s#endif\n' % (condition, string)
66
67
68 def messages_to_kind_enum(messages):
69     result = []
70     result.append('enum Kind {\n')
71     result += [surround_in_condition('    %s,\n' % message.id(), message.condition) for message in messages]
72     result.append('};\n')
73     return ''.join(result)
74
75 def function_parameter_type(type):
76     # Don't use references for built-in types.
77     builtin_types = frozenset([
78         'bool',
79         'float',
80         'double',
81         'uint8_t',
82         'uint16_t',
83         'uint32_t',
84         'uint64_t',
85         'int8_t',
86         'int16_t',
87         'int32_t',
88         'int64_t',
89     ])
90
91     if type in builtin_types:
92         return type
93
94     return 'const %s&' % type
95
96
97 def reply_parameter_type(type):
98     return '%s&' % type
99
100
101 def arguments_type(parameters, parameter_type_function):
102     arguments_type = 'CoreIPC::Arguments%d' % len(parameters)
103     if len(parameters):
104         arguments_type = '%s<%s>' % (arguments_type, ', '.join(parameter_type_function(parameter.type) for parameter in parameters))
105     return arguments_type
106
107
108 def base_class(message):
109     return arguments_type(message.parameters, function_parameter_type)
110
111
112 def reply_type(message):
113     return arguments_type(message.reply_parameters, reply_parameter_type)
114
115
116 def decode_type(message):
117     if message.has_attribute(VARIADIC_ATTRIBUTE):
118         return arguments_type(message.parameters[:-1], reply_parameter_type)
119     return base_class(message)
120
121
122 def delayed_reply_type(message):
123     return arguments_type(message.reply_parameters, function_parameter_type)
124
125
126 def message_to_struct_declaration(message):
127     result = []
128     function_parameters = [(function_parameter_type(x.type), x.name) for x in message.parameters]
129     result.append('struct %s : %s' % (message.name, base_class(message)))
130     result.append(' {\n')
131     result.append('    static const Kind messageID = %s;\n' % message.id())
132     result.append('    static const char* receiverName() { return messageReceiverName(); }\n')
133     result.append('    static const char* name() { return "%s"; }\n' % message.name)
134     result.append('\n')
135     if message.reply_parameters != None:
136         if message.has_attribute(DELAYED_ATTRIBUTE):
137             send_parameters = [(function_parameter_type(x.type), x.name) for x in message.reply_parameters]
138             result.append('    struct DelayedReply : public ThreadSafeRefCounted<DelayedReply> {\n')
139             result.append('        DelayedReply(PassRefPtr<CoreIPC::Connection>, PassOwnPtr<CoreIPC::MessageEncoder>);\n')
140             result.append('        ~DelayedReply();\n')
141             result.append('\n')
142             result.append('        bool send(%s);\n' % ', '.join([' '.join(x) for x in send_parameters]))
143             result.append('\n')
144             result.append('    private:\n')
145             result.append('        RefPtr<CoreIPC::Connection> m_connection;\n')
146             result.append('        OwnPtr<CoreIPC::MessageEncoder> m_encoder;\n')
147             result.append('    };\n\n')
148
149         result.append('    typedef %s Reply;\n' % reply_type(message))
150
151     result.append('    typedef %s DecodeType;\n' % decode_type(message))
152     if len(function_parameters):
153         result.append('    %s%s(%s)' % (len(function_parameters) == 1 and 'explicit ' or '', message.name, ', '.join([' '.join(x) for x in function_parameters])))
154         result.append('\n        : %s(%s)\n' % (base_class(message), ', '.join([x[1] for x in function_parameters])))
155         result.append('    {\n')
156         result.append('    }\n')
157     result.append('};\n')
158     return surround_in_condition(''.join(result), message.condition)
159
160
161 def struct_or_class(namespace, type):
162     structs = frozenset([
163         'WebCore::Animation',
164         'WebCore::EditorCommandsForKeyEvent',
165         'WebCore::CompositionUnderline',
166         'WebCore::DragSession',
167         'WebCore::FloatPoint3D',
168         'WebCore::FileChooserSettings',
169         'WebCore::GrammarDetail',
170         'WebCore::IdentityTransformOperation',
171         'WebCore::KeypressCommand',
172         'WebCore::Length',
173         'WebCore::MatrixTransformOperation',
174         'WebCore::Matrix3DTransformOperation',
175         'WebCore::NotificationContents',
176         'WebCore::PerspectiveTransformOperation',
177         'WebCore::PluginInfo',
178         'WebCore::PrintInfo',
179         'WebCore::RotateTransformOperation',
180         'WebCore::ScaleTransformOperation',
181         'WebCore::SkewTransformOperation',
182         'WebCore::TimingFunction',
183         'WebCore::TransformationMatrix',
184         'WebCore::TransformOperation',
185         'WebCore::TransformOperations',
186         'WebCore::TranslateTransformOperation',
187         'WebCore::ViewportAttributes',
188         'WebCore::WindowFeatures',
189         'WebKit::AttributedString',
190         'WebKit::ColorSpaceData',
191         'WebKit::ContextMenuState',
192         'WebKit::DictionaryPopupInfo',
193         'WebKit::DrawingAreaInfo',
194         'WebKit::EditorState',
195         'WebKit::NetworkProcessCreationParameters',
196         'WebKit::PlatformPopupMenuData',
197         'WebKit::PluginCreationParameters',
198         'WebKit::PluginProcessCreationParameters',
199         'WebKit::PrintInfo',
200         'WebKit::SecurityOriginData',
201         'WebKit::SharedWorkerProcessCreationParameters',
202         'WebKit::StatisticsData',
203         'WebKit::TextCheckerState',
204         'WebKit::WebNavigationDataStore',
205         'WebKit::WebPageCreationParameters',
206         'WebKit::WebPreferencesStore',
207         'WebKit::WebProcessCreationParameters',
208         'WebKit::WindowGeometry',
209     ])
210
211     qualified_name = '%s::%s' % (namespace, type)
212     if qualified_name in structs:
213         return 'struct %s' % type
214
215     return 'class %s' % type
216
217 def forward_declarations_for_namespace(namespace, types):
218     result = []
219     result.append('namespace %s {\n' % namespace)
220     result += ['    %s;\n' % struct_or_class(namespace, x) for x in types]
221     result.append('}\n')
222     return ''.join(result)
223
224
225 def forward_declarations_and_headers(receiver):
226     types_by_namespace = collections.defaultdict(set)
227
228     headers = set([
229         '"Arguments.h"',
230         '"MessageEncoder.h"',
231         '"MessageID.h"',
232     ])
233
234     for message in receiver.messages:
235         if message.reply_parameters != None and message.has_attribute(DELAYED_ATTRIBUTE):
236             headers.add('<wtf/ThreadSafeRefCounted.h>')
237             types_by_namespace['CoreIPC'].update(['Connection'])
238
239     for parameter in receiver.iterparameters():
240         type = parameter.type
241
242         if type.find('<') != -1:
243             # Don't forward declare class templates.
244             headers.update(headers_for_type(type))
245             continue
246
247         split = type.split('::')
248
249         if len(split) == 2:
250             namespace = split[0]
251             inner_type = split[1]
252             types_by_namespace[namespace].add(inner_type)
253         elif len(split) > 2:
254             # We probably have a nested struct, which means we can't forward declare it.
255             # Include its header instead.
256             headers.update(headers_for_type(type))
257
258     forward_declarations = '\n'.join([forward_declarations_for_namespace(namespace, types) for (namespace, types) in sorted(types_by_namespace.items())])
259     headers = ['#include %s\n' % header for header in sorted(headers)]
260
261     return (forward_declarations, headers)
262
263 def generate_messages_header(file):
264     receiver = parser.parse(file)
265     header_guard = messages_header_filename(receiver).replace('.', '_')
266
267     result = []
268
269     result.append(_license_header)
270
271     result.append('#ifndef %s\n' % header_guard)
272     result.append('#define %s\n\n' % header_guard)
273
274     if receiver.condition:
275         result.append('#if %s\n\n' % receiver.condition)
276
277     forward_declarations, headers = forward_declarations_and_headers(receiver)
278
279     result += headers
280     result.append('\n')
281
282     result.append(forward_declarations)
283     result.append('\n')
284
285     result.append('namespace Messages {\nnamespace %s {\n' % receiver.name)
286     result.append('\n')
287     result.append('static inline const char* messageReceiverName()\n')
288     result.append('{\n')
289     result.append('    return "%s";\n' % receiver.name)
290     result.append('}\n')
291     result.append('\n')
292
293     result.append(messages_to_kind_enum(receiver.messages))
294     result.append('\n')
295     result.append('\n'.join([message_to_struct_declaration(x) for x in receiver.messages]))
296     result.append('\n')
297     result.append('} // namespace %s\n} // namespace Messages\n' % receiver.name)
298
299     result.append('\nnamespace CoreIPC {\n\n')
300     result.append('template<> struct MessageKindTraits<Messages::%s::Kind> {\n' % receiver.name)
301     result.append('    static const MessageClass messageClass = MessageClass%s;\n' % receiver.name)
302     result.append('};\n')
303     result.append('\n} // namespace CoreIPC\n')
304
305     if receiver.condition:
306         result.append('\n#endif // %s\n' % receiver.condition)
307
308     result.append('\n#endif // %s\n' % header_guard)
309
310     return ''.join(result)
311
312
313 def handler_function(receiver, message):
314     if message.name.find('URL') == 0:
315         return '%s::%s' % (receiver.name, 'url' + message.name[3:])
316     return '%s::%s' % (receiver.name, message.name[0].lower() + message.name[1:])
317
318
319 def async_case_statement(receiver, message):
320     dispatch_function_args = ['decoder', 'this', '&%s' % handler_function(receiver, message)]
321     dispatch_function = 'handleMessage'
322     if message.has_attribute(VARIADIC_ATTRIBUTE):
323         dispatch_function += 'Variadic'
324     if message.has_attribute(DISPATCH_ON_CONNECTION_QUEUE_ATTRIBUTE):
325         dispatch_function += 'OnConnectionQueue'
326         dispatch_function_args.insert(0, 'connection')
327         
328     result = []
329     result.append('    case Messages::%s::%s:\n' % (receiver.name, message.id()))
330
331     result.append('        CoreIPC::%s<Messages::%s::%s>(%s);\n' % (dispatch_function, receiver.name, message.name, ', '.join(dispatch_function_args)))
332     if message.has_attribute(DISPATCH_ON_CONNECTION_QUEUE_ATTRIBUTE):
333         result.append('        didHandleMessage = true;\n')
334     result.append('        return;\n')
335     return surround_in_condition(''.join(result), message.condition)
336
337
338 def sync_case_statement(receiver, message):
339     dispatch_function = 'handleMessage'
340     if message.has_attribute(DELAYED_ATTRIBUTE):
341         dispatch_function += 'Delayed'
342     if message.has_attribute(VARIADIC_ATTRIBUTE):
343         dispatch_function += 'Variadic'
344
345     result = []
346     result.append('    case Messages::%s::%s:\n' % (receiver.name, message.id()))
347     result.append('        CoreIPC::%s<Messages::%s::%s>(%sdecoder, %sreplyEncoder, this, &%s);\n' % (dispatch_function, receiver.name, message.name, 'connection, ' if message.has_attribute(DELAYED_ATTRIBUTE) else '', '' if message.has_attribute(DELAYED_ATTRIBUTE) else '*', handler_function(receiver, message)))
348     result.append('        return;\n')
349
350     return surround_in_condition(''.join(result), message.condition)
351
352
353 def argument_coder_headers_for_type(type):
354     # Check for Vector.
355     match = re.search(r'Vector<(.+)>', type)
356     if match:
357         element_type = match.groups()[0].strip()
358         return ['"ArgumentCoders.h"'] + argument_coder_headers_for_type(element_type)
359
360     special_cases = {
361         'WTF::String': '"ArgumentCoders.h"',
362         'WebKit::InjectedBundleUserMessageEncoder': '"InjectedBundleUserMessageCoders.h"',
363         'WebKit::WebContextUserMessageEncoder': '"WebContextUserMessageCoders.h"',
364     }
365
366     if type in special_cases:
367         return [special_cases[type]]
368
369     split = type.split('::')
370     if len(split) < 2:
371         return []
372     if split[0] == 'WebCore':
373         return ['"WebCoreArgumentCoders.h"']
374
375     return []
376
377
378 def headers_for_type(type):
379     # Check for Vector.
380     match = re.search(r'Vector<(.+)>', type)
381     if match:
382         element_type = match.groups()[0].strip()
383         return ['<wtf/Vector.h>'] + headers_for_type(element_type)
384
385     special_cases = {
386         'WTF::String': ['<wtf/text/WTFString.h>'],
387         'WebCore::CompositionUnderline': ['<WebCore/Editor.h>'],
388         'WebCore::GrammarDetail': ['<WebCore/TextCheckerClient.h>'],
389         'WebCore::KeyframeValueList': ['<WebCore/GraphicsLayer.h>'],
390         'WebCore::KeypressCommand': ['<WebCore/KeyboardEvent.h>'],
391         'WebCore::FileChooserSettings': ['<WebCore/FileChooser.h>'],
392         'WebCore::PluginInfo': ['<WebCore/PluginData.h>'],
393         'WebCore::TextCheckingResult': ['<WebCore/TextCheckerClient.h>'],
394         'WebCore::ViewportAttributes': ['<WebCore/ViewportArguments.h>'],
395         'WebKit::InjectedBundleUserMessageEncoder': [],
396         'WebKit::WebContextUserMessageEncoder': [],
397         'WebKit::WebGestureEvent': ['"WebEvent.h"'],
398         'WebKit::WebLayerID': ['"WebLayerTreeInfo.h"'],
399         'WebKit::WebLayerInfo': ['"WebLayerTreeInfo.h"'],
400         'WebKit::WebKeyboardEvent': ['"WebEvent.h"'],
401         'WebKit::WebMouseEvent': ['"WebEvent.h"'],
402         'WebKit::WebTouchEvent': ['"WebEvent.h"'],
403         'WebKit::WebWheelEvent': ['"WebEvent.h"'],
404     }
405     if type in special_cases:
406         return special_cases[type]
407
408     # We assume that we must include a header for a type iff it has a scope
409     # resolution operator (::).
410     split = type.split('::')
411     if len(split) < 2:
412         return []
413     if split[0] == 'WebKit' or split[0] == 'CoreIPC':
414         return ['"%s.h"' % split[1]]
415     return ['<%s/%s.h>' % tuple(split)]
416
417
418 def generate_message_handler(file):
419     receiver = parser.parse(file)
420     headers = {
421         '"%s"' % messages_header_filename(receiver): [None],
422         '"HandleMessage.h"': [None],
423         '"MessageDecoder.h"': [None],
424     }
425
426     type_conditions = {}
427     for parameter in receiver.iterparameters():
428         if not parameter.type in type_conditions:
429             type_conditions[parameter.type] = []
430
431         if not parameter.condition in type_conditions[parameter.type]:
432             type_conditions[parameter.type].append(parameter.condition)
433
434     for parameter in receiver.iterparameters():
435         type = parameter.type
436         conditions = type_conditions[type]
437
438         argument_encoder_headers = argument_coder_headers_for_type(type)
439         if argument_encoder_headers:
440             for header in argument_encoder_headers:
441                 if header not in headers:
442                     headers[header] = []
443                 headers[header].extend(conditions)
444
445         type_headers = headers_for_type(type)
446         for header in type_headers:
447             if header not in headers:
448                 headers[header] = []
449             headers[header].extend(conditions)
450
451     for message in receiver.messages:
452         if message.reply_parameters is not None:
453             for reply_parameter in message.reply_parameters:
454                 type = reply_parameter.type
455                 argument_encoder_headers = argument_coder_headers_for_type(type)
456                 if argument_encoder_headers:
457                     for header in argument_encoder_headers:
458                         if header not in headers:
459                             headers[header] = []
460                         headers[header].append(message.condition)
461
462                 type_headers = headers_for_type(type)
463                 for header in type_headers:
464                     if header not in headers:
465                         headers[header] = []
466                     headers[header].append(message.condition)
467
468
469     result = []
470
471     result.append(_license_header)
472     result.append('#include "config.h"\n')
473     result.append('\n')
474
475     if receiver.condition:
476         result.append('#if %s\n\n' % receiver.condition)
477
478     result.append('#include "%s.h"\n\n' % receiver.name)
479     for headercondition in sorted(headers):
480         if headers[headercondition] and not None in headers[headercondition]:
481             result.append('#if %s\n' % ' || '.join(set(headers[headercondition])))
482             result += ['#include %s\n' % headercondition]
483             result.append('#endif\n')
484         else:
485             result += ['#include %s\n' % headercondition]
486     result.append('\n')
487
488     sync_delayed_messages = []
489     for message in receiver.messages:
490         if message.reply_parameters != None and message.has_attribute(DELAYED_ATTRIBUTE):
491             sync_delayed_messages.append(message)
492
493     if sync_delayed_messages:
494         result.append('namespace Messages {\n\nnamespace %s {\n\n' % receiver.name)
495
496         for message in sync_delayed_messages:
497             send_parameters = [(function_parameter_type(x.type), x.name) for x in message.reply_parameters]
498
499             if message.condition:
500                 result.append('#if %s\n\n' % message.condition)
501             
502             result.append('%s::DelayedReply::DelayedReply(PassRefPtr<CoreIPC::Connection> connection, PassOwnPtr<CoreIPC::MessageEncoder> encoder)\n' % message.name)
503             result.append('    : m_connection(connection)\n')
504             result.append('    , m_encoder(encoder)\n')
505             result.append('{\n')
506             result.append('}\n')
507             result.append('\n')
508             result.append('%s::DelayedReply::~DelayedReply()\n' % message.name)
509             result.append('{\n')
510             result.append('    ASSERT(!m_connection);\n')
511             result.append('}\n')
512             result.append('\n')
513             result.append('bool %s::DelayedReply::send(%s)\n' % (message.name, ', '.join([' '.join(x) for x in send_parameters])))
514             result.append('{\n')
515             result.append('    ASSERT(m_encoder);\n')
516             result += ['    m_encoder->encode(%s);\n' % x.name for x in message.reply_parameters]
517             result.append('    bool result = m_connection->sendSyncReply(m_encoder.release());\n')
518             result.append('    m_connection = nullptr;\n')
519             result.append('    return result;\n')
520             result.append('}\n')
521             result.append('\n')
522
523             if message.condition:
524                 result.append('#endif\n\n')
525
526         result.append('} // namespace %s\n\n} // namespace Messages\n\n' % receiver.name)
527
528     result.append('namespace WebKit {\n\n')
529
530     async_dispatch_on_connection_queue_messages = []
531     sync_dispatch_on_connection_queue_messages = []
532     async_messages = []
533     sync_messages = []
534     for message in receiver.messages:
535         if message.reply_parameters is not None:
536             if message.has_attribute(DISPATCH_ON_CONNECTION_QUEUE_ATTRIBUTE):
537                 sync_dispatch_on_connection_queue_messages.append(message)
538             else:
539                 sync_messages.append(message)
540         else:
541             if message.has_attribute(DISPATCH_ON_CONNECTION_QUEUE_ATTRIBUTE):
542                 async_dispatch_on_connection_queue_messages.append(message)
543             else:
544                 async_messages.append(message)
545
546     if async_dispatch_on_connection_queue_messages:
547         result.append('void %s::didReceive%sMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder, bool& didHandleMessage)\n' % (receiver.name, receiver.name))
548         result.append('{\n')
549         result.append('#if COMPILER(MSVC)\n')
550         result.append('#pragma warning(push)\n')
551         result.append('#pragma warning(disable: 4065)\n')
552         result.append('#endif\n')
553         result.append('    switch (messageID.get<Messages::%s::Kind>()) {\n' % receiver.name)
554         result += [async_case_statement(receiver, message) for message in async_dispatch_on_connection_queue_messages]
555         result.append('    default:\n')
556         result.append('        return;\n')
557         result.append('    }\n')
558         result.append('#if COMPILER(MSVC)\n')
559         result.append('#pragma warning(pop)\n')
560         result.append('#endif\n')
561         result.append('}\n\n')
562
563     if async_messages:
564         result.append('void %s::didReceive%sMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder)\n' % (receiver.name, receiver.name))
565         result.append('{\n')
566         result.append('    switch (messageID.get<Messages::%s::Kind>()) {\n' % receiver.name)
567         result += [async_case_statement(receiver, message) for message in async_messages]
568         result.append('    default:\n')
569         result.append('        break;\n')
570         result.append('    }\n\n')
571         result.append('    ASSERT_NOT_REACHED();\n')
572         result.append('}\n')
573
574     if sync_messages:
575         result.append('\n')
576         result.append('void %s::didReceiveSync%sMessage(CoreIPC::Connection*%s, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder)\n' % (receiver.name, receiver.name, ' connection' if sync_delayed_messages else ''))
577         result.append('{\n')
578         result.append('    switch (messageID.get<Messages::%s::Kind>()) {\n' % receiver.name)
579         result += [sync_case_statement(receiver, message) for message in sync_messages]
580         result.append('    default:\n')
581         result.append('        break;\n')
582         result.append('    }\n\n')
583         result.append('    ASSERT_NOT_REACHED();\n')
584         result.append('}\n')
585
586     result.append('\n} // namespace WebKit\n')
587
588     if receiver.condition:
589         result.append('\n#endif // %s\n' % receiver.condition)
590
591     return ''.join(result)