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