def decode_msg(raw_msg):
try:<EOL><INDENT>msg_data = json.loads(raw_msg)<EOL><DEDENT>except ValueError:<EOL><INDENT>raise RpcParseError<EOL><DEDENT>if '<STR_LIT>' not in msg_data or not msg_data['<STR_LIT>'] == JSONRPC:<EOL><INDENT>raise RpcInvalidRequestError(msg_id=msg_data.get('<STR_LIT:id>', None))<EOL><DEDENT>if not len(set(['<STR_LIT:error>', '<STR_LIT:result>', '<STR_LIT>']) & set(msg_data)) == <NUM_LIT:1>:<EOL><INDENT>raise RpcInvalidRequestError(msg_id=msg_data.get('<STR_LIT:id>', None))<EOL><DEDENT>if '<STR_LIT>' in msg_data:<EOL><INDENT>if '<STR_LIT:id>' in msg_data and msg_data['<STR_LIT:id>'] is not None:<EOL><INDENT>msg_type = JsonRpcMsgTyp.REQUEST<EOL><DEDENT>else:<EOL><INDENT>msg_type = JsonRpcMsgTyp.NOTIFICATION<EOL><DEDENT><DEDENT>elif '<STR_LIT:result>' in msg_data:<EOL><INDENT>msg_type = JsonRpcMsgTyp.RESULT<EOL><DEDENT>elif '<STR_LIT:error>' in msg_data:<EOL><INDENT>msg_type = JsonRpcMsgTyp.ERROR<EOL><DEDENT>if msg_type in (JsonRpcMsgTyp.REQUEST, JsonRpcMsgTyp.NOTIFICATION):<EOL><INDENT>if type(msg_data['<STR_LIT>']) is not str:<EOL><INDENT>raise RpcInvalidRequestError<EOL><DEDENT>if '<STR_LIT>' not in msg_data:<EOL><INDENT>msg_data['<STR_LIT>'] = None<EOL><DEDENT>if '<STR_LIT:id>' not in msg_data:<EOL><INDENT>msg_data['<STR_LIT:id>'] = None<EOL><DEDENT><DEDENT>if msg_type in (JsonRpcMsgTyp.RESULT, JsonRpcMsgTyp.ERROR):<EOL><INDENT>if '<STR_LIT:id>' not in msg_data:<EOL><INDENT>raise RpcInvalidRequestError(msg_id=msg_data.get('<STR_LIT:id>', None))<EOL><DEDENT><DEDENT>if msg_type == JsonRpcMsgTyp.ERROR:<EOL><INDENT>if type(msg_data['<STR_LIT:error>']) is not dict:<EOL><INDENT>raise RpcInvalidRequestError(msg_id=msg_data.get('<STR_LIT:id>', None))<EOL><DEDENT>if not len(set(['<STR_LIT:code>', '<STR_LIT:message>']) & set(msg_data['<STR_LIT:error>'])) == <NUM_LIT:2>:<EOL><INDENT>raise RpcInvalidRequestError(msg_id=msg_data.get('<STR_LIT:id>', None))<EOL><DEDENT>if not msg_data['<STR_LIT:error>']['<STR_LIT:code>'] in RpcError.lookup_table.keys():<EOL><INDENT>raise RpcInvalidRequestError(msg_id=msg_data.get('<STR_LIT:id>', None))<EOL><DEDENT>if '<STR_LIT:data>' not in msg_data['<STR_LIT:error>']:<EOL><INDENT>msg_data['<STR_LIT:error>']['<STR_LIT:data>'] = None<EOL><DEDENT><DEDENT>return JsonRpcMsg(msg_type, msg_data)<EOL>
Decodes jsonrpc 2.0 raw message objects into JsonRpcMsg objects.

Examples:
    Request:
        {
            "jsonrpc": "2.0",
            "id": 1,
            "method": "subtract",
            "params": [42, 23]
        }

    Notification:
        {
            "jsonrpc": "2.0",
            "method": "clock",
            "params": "12:00",
        }

    Response:
        {
            "jsonrpc": "2.0",
            "id": 1,
            "result": 0,
        }

    Error:
        {
            "jsonrpc": "2.0",
            "id": 1,
            "error": {
                "code": -32600,
                "message": "Invalid request",
                "data": null
            }
        }