def read_message(self):
msg = "<STR_LIT>"<EOL>num_blank_lines = <NUM_LIT:0><EOL>while True:<EOL><INDENT>with self._reader_lock:<EOL><INDENT>line = self.input_stream.readline()<EOL><DEDENT>if line == "<STR_LIT>":<EOL><INDENT>break<EOL><DEDENT>elif line == "<STR_LIT>":<EOL><INDENT>raise StormWentAwayError()<EOL><DEDENT>elif line == "<STR_LIT:\n>":<EOL><INDENT>num_blank_lines += <NUM_LIT:1><EOL>if num_blank_lines % <NUM_LIT:1000> == <NUM_LIT:0>:<EOL><INDENT>log.warn(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>",<EOL>num_blank_lines,<EOL>)<EOL><DEDENT>continue<EOL><DEDENT>msg = "<STR_LIT>".format(msg, line[<NUM_LIT:0>:-<NUM_LIT:1>])<EOL><DEDENT>try:<EOL><INDENT>return json.loads(msg)<EOL><DEDENT>except Exception:<EOL><INDENT>log.error("<STR_LIT>", msg, exc_info=True)<EOL>raise<EOL><DEDENT>
The Storm multilang protocol consists of JSON messages followed by
        a newline and "end\n".

        All of Storm's messages (for either bolts or spouts) should be of the
        form::

            '<command or task_id form prior emit>\\nend\\n'

        Command example, an incoming Tuple to a bolt::

            '{ "id": "-6955786537413359385",  "comp": "1", "stream": "1", "task": 9, "tuple": ["snow white and the seven dwarfs", "field2", 3]}\\nend\\n'

        Command example for a spout to emit its next Tuple::

            '{"command": "next"}\\nend\\n'

        Example, the task IDs a prior emit was sent to::

            '[12, 22, 24]\\nend\\n'

        The edge case of where we read ``''`` from ``input_stream`` indicating
        EOF, usually means that communication with the supervisor has been
        severed.