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