<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def ParseMessage(self, parser_mediator, key, date_time, tokens):
 """Produces an event from a syslog body that matched one of the grammars. Args: parser_mediator (ParserMediator):
 mediates interactions between parsers and other components, such as storage and dfvfs. key (str):
 name of the matching grammar. date_time (dfdatetime.DateTimeValues):
 date and time values. tokens (dict[str, str]):
 tokens derived from a syslog message based on the defined grammar. Raises: ValueError: If an unknown key is provided. """

    if key not in ('failed_connection', 'login', 'opened_connection'):
      raise ValueError('Unknown grammar key: {0:s}'.format(key))

    if key == 'login':
      event_data = SSHLoginEventData()

    elif key == 'failed_connection':
      event_data = SSHFailedConnectionEventData()

    elif key == 'opened_connection':
      event_data = SSHOpenedConnectionEventData()

    event_data.address = tokens.get('address', None)
    event_data.authentication_method = tokens.get(
        'authentication_method', None)
    event_data.body = tokens.get('body', None)
    event_data.fingerprint = tokens.get('fingerprint', None)
    event_data.hostname = tokens.get('hostname', None)
    # TODO: pass line number to offset or remove.
    event_data.offset = 0
    event_data.pid = tokens.get('pid', None)
    event_data.protocol = tokens.get('protocol', None)
    event_data.port = tokens.get('port', None)
    event_data.reporter = tokens.get('reporter', None)
    event_data.severity = tokens.get('severity', None)
    event_data.username = tokens.get('username', None)

    event = time_events.DateTimeValuesEvent(
        date_time, definitions.TIME_DESCRIPTION_WRITTEN)
    parser_mediator.ProduceEventWithEventData(event, event_data)