2011-04-06 Ilya Tikhonovsky <loislo@chromium.org>
authorloislo@chromium.org <loislo@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Apr 2011 14:16:56 +0000 (14:16 +0000)
committerloislo@chromium.org <loislo@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Apr 2011 14:16:56 +0000 (14:16 +0000)
        Reviewed by Yury Semikhatsky.

        Web Inspector: migrate Inspector protocol messages format to JSON-RPC.
        https://bugs.webkit.org/show_bug.cgi?id=57957

        There is not a significant difference between  inspector messages spec and and JSON-RPC 2.0 messages spec.
        Also JSON-RPC has a pretty clear specification for error descriptions which we haven't.
        It was decided that we will use it.

        the list of renames:
        1) type-> /dev/null
        2) domain + '.' + event => method // for events
        3) domain + '.' + command => method // for requests
        4) requestId => id // for responses
        5) arguments => params // for requests
        6) data => params // for events
        7) body => result // for responses

        protocolErrors and error properties will be converted to JSON-RPC error format.
        The order of properties in messages also will be adjusted.
        The only thing that looks unnecessary is jsonrpc property.

        * inspector/protocol/console-agent-expected.txt:
        * inspector/protocol/runtime-agent-expected.txt:
        * inspector/report-API-errors-expected.txt:
        * inspector/report-API-errors.html:
        * inspector/report-protocol-errors-expected.txt:
        * inspector/report-protocol-errors.html:
2011-04-06  Ilya Tikhonovsky  <loislo@chromium.org>

        Reviewed by Yury Semikhatsky.

        Web Inspector: migrate Inspector protocol messages format to JSON-RPC.
        https://bugs.webkit.org/show_bug.cgi?id=57957

        There is not a significant difference between  inspector messages spec and and JSON-RPC 2.0 messages spec.
        Also JSON-RPC has a pretty clear specification for error descriptions which we haven't.
        It was decided that we will use it.

        the list of renames:
        1) type-> /dev/null
        2) domain + '.' + event => method // for events
        3) domain + '.' + command => method // for requests
        4) requestId => id // for responses
        5) arguments => params // for requests
        6) data => params // for events
        7) body => result // for responses

        protocolErrors and error properties will be converted to JSON-RPC error format.
        The order of properties in messages also will be adjusted.
        The only thing that looks unnecessary is jsonrpc property.

        * inspector/CodeGeneratorInspector.pm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@83171 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/inspector/protocol/console-agent-expected.txt
LayoutTests/inspector/protocol/runtime-agent-expected.txt
LayoutTests/inspector/report-API-errors-expected.txt
LayoutTests/inspector/report-API-errors.html
LayoutTests/inspector/report-protocol-errors-expected.txt
LayoutTests/inspector/report-protocol-errors.html
Source/WebCore/ChangeLog
Source/WebCore/inspector/CodeGeneratorInspector.pm

index cfa561d..eb35487 100644 (file)
@@ -1,3 +1,34 @@
+2011-04-06  Ilya Tikhonovsky  <loislo@chromium.org>
+
+        Reviewed by Yury Semikhatsky.
+
+        Web Inspector: migrate Inspector protocol messages format to JSON-RPC.
+        https://bugs.webkit.org/show_bug.cgi?id=57957
+
+        There is not a significant difference between  inspector messages spec and and JSON-RPC 2.0 messages spec.
+        Also JSON-RPC has a pretty clear specification for error descriptions which we haven't.
+        It was decided that we will use it.
+
+        the list of renames:
+        1) type-> /dev/null
+        2) domain + '.' + event => method // for events
+        3) domain + '.' + command => method // for requests
+        4) requestId => id // for responses
+        5) arguments => params // for requests
+        6) data => params // for events
+        7) body => result // for responses
+
+        protocolErrors and error properties will be converted to JSON-RPC error format.
+        The order of properties in messages also will be adjusted.
+        The only thing that looks unnecessary is jsonrpc property.
+
+        * inspector/protocol/console-agent-expected.txt:
+        * inspector/protocol/runtime-agent-expected.txt:
+        * inspector/report-API-errors-expected.txt:
+        * inspector/report-API-errors.html:
+        * inspector/report-protocol-errors-expected.txt:
+        * inspector/report-protocol-errors.html:
+
 2011-04-07  Kent Tamura  <tkent@chromium.org>
 
         [Chromium] Move Leopard-specific images to chromium-mac-leopard, and
index 3325ff0..bbd5e6d 100644 (file)
@@ -7,16 +7,15 @@ ConsoleAgent.disable()
 
 request:
 {
+    method : "Console.disable"
     id : <number>
-    domain : "Console"
-    command : "disable"
-    arguments : {
-    }
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -24,19 +23,16 @@ ConsoleAgent.enable()
 
 request:
 {
+    method : "Console.enable"
     id : <number>
-    domain : "Console"
-    command : "enable"
-    arguments : {
-    }
 }
 
 response:
 {
-    requestId : <number>
-    body : {
+    result : {
         expiredMessagesCount : 0
     }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -44,22 +40,19 @@ RuntimeAgent.evaluate("console.info('test'); console.info('test')","test-group",
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "evaluate"
-    arguments : {
+    method : "Runtime.evaluate"
+    params : {
         expression : "console.info('test'); console.info('test')"
         objectGroup : "test-group"
         includeCommandLineAPI : false
     }
+    id : <number>
 }
 
 event ConsoleAgent.consoleMessage
 {
-    type : "event"
-    domain : "Console"
-    event : "consoleMessage"
-    data : {
+    method : "Console.consoleMessage"
+    params : {
         messageObj : {
             source : 3
             type : 0
@@ -81,23 +74,21 @@ event ConsoleAgent.consoleMessage
 
 event ConsoleAgent.consoleMessageRepeatCountUpdated
 {
-    type : "event"
-    domain : "Console"
-    event : "consoleMessageRepeatCountUpdated"
-    data : {
+    method : "Console.consoleMessageRepeatCountUpdated"
+    params : {
         count : 2
     }
 }
 
 response:
 {
-    requestId : <number>
-    body : {
+    result : {
         result : {
             type : "undefined"
             description : "undefined"
         }
     }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -105,25 +96,20 @@ ConsoleAgent.clearConsoleMessages()
 
 request:
 {
+    method : "Console.clearConsoleMessages"
     id : <number>
-    domain : "Console"
-    command : "clearConsoleMessages"
-    arguments : {
-    }
 }
 
 event ConsoleAgent.consoleMessagesCleared
 {
-    type : "event"
-    domain : "Console"
-    event : "consoleMessagesCleared"
-    data : {
-    }
+    method : "Console.consoleMessagesCleared"
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -131,17 +117,18 @@ ConsoleAgent.setMonitoringXHREnabled(true)
 
 request:
 {
-    id : <number>
-    domain : "Console"
-    command : "setMonitoringXHREnabled"
-    arguments : {
+    method : "Console.setMonitoringXHREnabled"
+    params : {
         enabled : true
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -149,17 +136,18 @@ ConsoleAgent.setMonitoringXHREnabled(false)
 
 request:
 {
-    id : <number>
-    domain : "Console"
-    command : "setMonitoringXHREnabled"
-    arguments : {
+    method : "Console.setMonitoringXHREnabled"
+    params : {
         enabled : false
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -167,17 +155,18 @@ ConsoleAgent.addInspectedNode(<number>)
 
 request:
 {
-    id : <number>
-    domain : "Console"
-    command : "addInspectedNode"
-    arguments : {
+    method : "Console.addInspectedNode"
+    params : {
         nodeId : 1
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 ===========================================================
index 92dbfe4..edaa58d 100644 (file)
@@ -5,20 +5,18 @@ RuntimeAgent.evaluate("testObject","test",false)
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "evaluate"
-    arguments : {
+    method : "Runtime.evaluate"
+    params : {
         expression : "testObject"
         objectGroup : "test"
         includeCommandLineAPI : false
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
-    body : {
+    result : {
         result : {
             objectId : <string>
             hasChildren : true
@@ -26,6 +24,7 @@ response:
             description : "TestObject"
         }
     }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -33,19 +32,17 @@ RuntimeAgent.evaluate("testObject","test")
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "evaluate"
-    arguments : {
+    method : "Runtime.evaluate"
+    params : {
         expression : "testObject"
         objectGroup : "test"
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
-    body : {
+    result : {
         result : {
             objectId : <string>
             hasChildren : true
@@ -53,6 +50,7 @@ response:
             description : "TestObject"
         }
     }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -60,24 +58,23 @@ RuntimeAgent.evaluateOn(<string>,"this.assignedByEvaluateOn = \"evaluateOn funct
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "evaluateOn"
-    arguments : {
+    method : "Runtime.evaluateOn"
+    params : {
         objectId : <string>
         expression : "this.assignedByEvaluateOn = "evaluateOn function works fine";"
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
-    body : {
+    result : {
         result : {
             type : "undefined"
             description : "undefined"
         }
     }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -85,19 +82,20 @@ RuntimeAgent.setPropertyValue(<string>,"assignedBySetPropertyValue","true")
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "setPropertyValue"
-    arguments : {
+    method : "Runtime.setPropertyValue"
+    params : {
         objectId : <string>
         propertyName : "assignedBySetPropertyValue"
         expression : "true"
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -105,19 +103,20 @@ RuntimeAgent.setPropertyValue(<string>,"removedBySetPropertyValue","")
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "setPropertyValue"
-    arguments : {
+    method : "Runtime.setPropertyValue"
+    params : {
         objectId : <string>
         propertyName : "removedBySetPropertyValue"
         expression : ""
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -125,19 +124,17 @@ RuntimeAgent.getProperties(<string>,false)
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "getProperties"
-    arguments : {
+    method : "Runtime.getProperties"
+    params : {
         objectId : <string>
         ignoreHasOwnProperty : false
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
-    body : {
+    result : {
         result : {
             0 : {
                 name : "assignedByEvaluateOn"
@@ -164,6 +161,7 @@ response:
             }
         }
     }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -171,17 +169,18 @@ RuntimeAgent.releaseObject(<string>)
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "releaseObject"
-    arguments : {
+    method : "Runtime.releaseObject"
+    params : {
         objectId : <string>
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 -----------------------------------------------------------
@@ -189,17 +188,18 @@ RuntimeAgent.releaseObjectGroup("test")
 
 request:
 {
-    id : <number>
-    domain : "Runtime"
-    command : "releaseObjectGroup"
-    arguments : {
+    method : "Runtime.releaseObjectGroup"
+    params : {
         objectGroup : "test"
     }
+    id : <number>
 }
 
 response:
 {
-    requestId : <number>
+    result : {
+    }
+    id : <number>
 }
 
 ===========================================================
index f794348..2066d12 100644 (file)
@@ -1,8 +1,8 @@
 Tests that InspectorBackendStub is catching incorrect arguments.
 
-Protocol Error: Invalid type of argument 'enabled' for 'ConsoleAgent.setMonitoringXHREnabled' call. It should be 'boolean' but it is 'number'.
-Protocol Error: Invalid number of arguments for 'ConsoleAgent.setMonitoringXHREnabled' call. It should have the next arguments '{"enabled":{"optional":false,"type":"boolean"}}'.
-Protocol Error: Optional callback argument for 'ConsoleAgent.setMonitoringXHREnabled' call should be a function but its type is 'string'.
+Protocol Error: Invalid type of argument 'enabled' for method 'ConsoleAgent.setMonitoringXHREnabled' call. It should be 'boolean' but it is 'number'.
+Protocol Error: Invalid number of arguments for method 'ConsoleAgent.setMonitoringXHREnabled' call. It should have the next arguments '{"enabled":{"optional":false,"type":"boolean"}}'.
+Protocol Error: Optional callback argument for method 'ConsoleAgent.setMonitoringXHREnabled' call should be a function but its type is 'string'.
 Protocol Error: the message is for non-existing domain 'wrongDomain'
 Protocol Error: Attempted to dispatch an unimplemented method 'Inspector.something-strange'
 
index bd84469..b67025b 100644 (file)
@@ -18,8 +18,8 @@ function test()
     RuntimeAgent.evaluate("true", "test");
     RuntimeAgent.evaluate("true", "test", function(){});
     RuntimeAgent.evaluate("true", "test", undefined, function(){});
-    InspectorBackend.dispatch('{"type": "event", "domain": "wrongDomain", "event": "something-strange", "data": {}}');
-    InspectorBackend.dispatch('{"type": "event", "domain": "Inspector", "event": "something-strange", "data": {}}');
+    InspectorBackend.dispatch('{"method": "wrongDomain.something-strange", "params": {}}');
+    InspectorBackend.dispatch('{"method": "Inspector.something-strange", "params": {}}');
 
     InspectorTest.completeTest();
 }
index 7b16696..7687349 100644 (file)
 Tests that InspectorBackendDispatcher is catching incorrect messages.
 
 {
-    requestId : 0
-    protocolErrors : {
-        0 : "Protocol Error: Invalid message format. Message should be in JSON format."
+    error : {
+        code : -32700
+        message : "Parse error."
+        data : {
+            0 : "Message should be in JSON format."
+        }
     }
+    id : 0
 }
 {
-    requestId : 0
-    protocolErrors : {
-        0 : "Protocol Error: Invalid message format. 'command' property wasn't found."
+    error : {
+        code : -32600
+        message : "Invalid Request."
+        data : {
+            0 : "Invalid message format. 'method' property wasn't found."
+        }
     }
+    id : 0
 }
 {
-    requestId : 0
-    protocolErrors : {
-        0 : "Protocol Error: Invalid message format. The type of 'command' property should be string."
+    error : {
+        code : -32600
+        message : "Invalid Request."
+        data : {
+            0 : "Invalid message format. The type of 'method' property should be string."
+        }
     }
+    id : 0
 }
 {
-    requestId : 0
-    protocolErrors : {
-        0 : "Protocol Error: Invalid message format. 'id' property was not found in the request."
+    error : {
+        code : -32600
+        message : "Invalid Request."
+        data : {
+            0 : "Invalid message format. 'id' property was not found in the request."
+        }
     }
+    id : 0
 }
 {
-    requestId : 0
-    protocolErrors : {
-        0 : "Protocol Error: Invalid message format. The type of 'id' property should be number."
+    error : {
+        code : -32600
+        message : "Invalid Request."
+        data : {
+            0 : "Invalid message format. The type of 'id' property should be number."
+        }
     }
+    id : 0
 }
 {
-    requestId : 1
-    protocolErrors : {
-        0 : "Protocol Error: Invalid command was received. 'test' wasn't found in domain DOM."
+    error : {
+        code : -32601
+        message : "Method not found."
+        data : {
+            0 : "Invalid method name was received. 'DOM.test' wasn't found."
+        }
     }
+    id : 1
 }
 {
-    requestId : 2
-    protocolErrors : {
-        0 : "Protocol Error: 'arguments' property with type 'object' was not found."
+    error : {
+        code : -32602
+        message : "Invalid params."
+        data : {
+            0 : "'params' property with type 'object' was not found."
+        }
     }
+    id : 2
 }
 {
-    requestId : 3
-    protocolErrors : {
-        0 : "Protocol Error: 'arguments' property with type 'object' was not found."
+    error : {
+        code : -32602
+        message : "Invalid params."
+        data : {
+            0 : "'params' property with type 'object' was not found."
+        }
     }
+    id : 3
 }
 {
-    requestId : 4
-    protocolErrors : {
-        0 : "Protocol Error: Argument 'frameId' with type 'String' was not found."
-        1 : "Protocol Error: Argument 'url' with type 'String' was not found."
+    error : {
+        code : -32602
+        message : "Invalid params."
+        data : {
+            0 : "Parameter 'frameId' with type 'String' was not found."
+            1 : "Parameter 'url' with type 'String' was not found."
+        }
     }
+    id : 4
 }
 {
-    requestId : 5
-    protocolErrors : {
-        0 : "Protocol Error: Argument 'url' with type 'String' was not found."
+    error : {
+        code : -32602
+        message : "Invalid params."
+        data : {
+            0 : "Parameter 'url' with type 'String' was not found."
+        }
     }
+    id : 5
 }
 
index adfdc7f..715ffa8 100644 (file)
@@ -8,14 +8,14 @@ function test()
     var messages = [
         'some wrong string',
         '{}',
-        '{"command":1}',
-        '{"domain":"Network","command":"resourceContent"}',
-        '{"id":"not a number","domain":"Network","command":"resourceContent"}',
-        '{"id":1,"domain":"DOM","command":"test"}',
-        '{"id":2,"domain":"Network","command":"getResourceContent"}',
-        '{"id":3,"domain":"Network","command":"getResourceContent","arguments":[]}',
-        '{"id":4,"domain":"Network","command":"getResourceContent","arguments":{}}',
-        '{"id":5,"domain":"Network","command":"getResourceContent","arguments":{"frameId":"not a number"}}',
+        '{"method":1}',
+        '{"method":"resourceContent"}',
+        '{"id":"not a number","method":"Network.resourceContent"}',
+        '{"id":1,"method":"DOM.test"}',
+        '{"id":2,"method":"Network.getResourceContent"}',
+        '{"id":3,"method":"Network.getResourceContent","params":[]}',
+        '{"id":4,"method":"Network.getResourceContent","params":{}}',
+        '{"id":5,"method":"Network.getResourceContent","params":{"frameId":"not a number"}}',
     ];
     var numberOfReports = 0;
 
index 69d0355..c824c03 100644 (file)
@@ -1,3 +1,29 @@
+2011-04-06  Ilya Tikhonovsky  <loislo@chromium.org>
+
+        Reviewed by Yury Semikhatsky.
+
+        Web Inspector: migrate Inspector protocol messages format to JSON-RPC.
+        https://bugs.webkit.org/show_bug.cgi?id=57957
+
+        There is not a significant difference between  inspector messages spec and and JSON-RPC 2.0 messages spec.
+        Also JSON-RPC has a pretty clear specification for error descriptions which we haven't.
+        It was decided that we will use it.
+
+        the list of renames:
+        1) type-> /dev/null
+        2) domain + '.' + event => method // for events
+        3) domain + '.' + command => method // for requests
+        4) requestId => id // for responses
+        5) arguments => params // for requests
+        6) data => params // for events
+        7) body => result // for responses
+
+        protocolErrors and error properties will be converted to JSON-RPC error format.
+        The order of properties in messages also will be adjusted.
+        The only thing that looks unnecessary is jsonrpc property.
+
+        * inspector/CodeGeneratorInspector.pm:
+
 2011-04-07  Ryosuke Niwa  <rniwa@webkit.org>
 
         Reviewed by Eric Seidel.
index a9ebf38..9029358 100644 (file)
@@ -192,6 +192,9 @@ $typeTransform{"void"} = {
     "forward" => "",
     "header" => ""
 };
+$typeTransform{"Vector"} = {
+    "header" => "wtf/Vector.h"
+};
 
 # Default License Templates
 
@@ -369,13 +372,13 @@ sub generateFrontendFunction
     push(@function, "void ${frontendClassName}::${domain}::${functionName}(${arguments})");
     push(@function, "{");
     push(@function, "    RefPtr<InspectorObject> ${functionName}Message = InspectorObject::create();");
-    push(@function, "    ${functionName}Message->setString(\"type\", \"event\");");
-    push(@function, "    ${functionName}Message->setString(\"domain\", \"$domain\");");
-    push(@function, "    ${functionName}Message->setString(\"event\", \"$functionName\");");
-    push(@function, "    RefPtr<InspectorObject> dataObject = InspectorObject::create();");
-    my @pushArguments = map("    dataObject->set" . typeTraits($_->type, "JSONType") . "(\"" . $_->name . "\", " . $_->name . ");", @argsFiltered);
-    push(@function, @pushArguments);
-    push(@function, "    ${functionName}Message->setObject(\"data\", dataObject);");
+    push(@function, "    ${functionName}Message->setString(\"method\", \"$domain.$functionName\");");
+    if (scalar(@argsFiltered)) {
+        push(@function, "    RefPtr<InspectorObject> paramsObject = InspectorObject::create();");
+        my @pushArguments = map("    paramsObject->set" . typeTraits($_->type, "JSONType") . "(\"" . $_->name . "\", " . $_->name . ");", @argsFiltered);
+        push(@function, @pushArguments);
+        push(@function, "    ${functionName}Message->setObject(\"params\", paramsObject);");
+    }
     push(@function, "    m_inspectorFrontendChannel->sendMessageToFrontend(${functionName}Message->toJSONString());");
     push(@function, "}");
     push(@function, "");
@@ -397,12 +400,13 @@ sub generateBackendFunction
 
     my $functionName = $function->signature->name;
     my $fullQualifiedFunctionName = $interface->name . "_" . $function->signature->name;
+    my $fullQualifiedFunctionNameDot = $interface->name . "." . $function->signature->name;
 
     push(@backendConstantDeclarations, "    static const char* ${fullQualifiedFunctionName}Cmd;");
-    push(@backendConstantDefinitions, "const char* ${backendClassName}::${fullQualifiedFunctionName}Cmd = \"${fullQualifiedFunctionName}\";");
+    push(@backendConstantDefinitions, "const char* ${backendClassName}::${fullQualifiedFunctionName}Cmd = \"${fullQualifiedFunctionNameDot}\";");
 
     map($backendTypes{$_->type} = 1, @{$function->parameters}); # register required types
-    my @inArgs = grep($_->direction eq "in" && !($_->name eq "callId") , @{$function->parameters});
+    my @inArgs = grep($_->direction eq "in", @{$function->parameters});
     my @outArgs = grep($_->direction eq "out", @{$function->parameters});
     
     my $signature = "    void ${fullQualifiedFunctionName}(long callId, InspectorObject* requestMessageObject);";
@@ -422,25 +426,27 @@ sub generateBackendFunction
     $backendTypes{$domain} = 1;
     $backendDomains{$domain} = 1;
     push(@function, "    if (!$domainAccessor)");
-    push(@function, "        protocolErrors->pushString(\"Protocol Error: $domain handler is not available.\");");
+    push(@function, "        protocolErrors->pushString(\"$domain handler is not available.\");");
     push(@function, "");
 
     # declare local variables for out arguments.
-    push(@function, map("    " . typeTraits($_->type, "variable") . " out_" . $_->name . " = " . typeTraits($_->type, "defaultValue") . ";", @outArgs));
-    push(@function, "");
+    if (scalar(@outArgs)) {
+        push(@function, map("    " . typeTraits($_->type, "variable") . " out_" . $_->name . " = " . typeTraits($_->type, "defaultValue") . ";", @outArgs));
+        push(@function, "");
+    }
     push(@function, "    ErrorString error;");
     push(@function, "");
 
     my $indent = "";
     if (scalar(@inArgs)) {
-        push(@function, "    if (RefPtr<InspectorObject> argumentsContainer = requestMessageObject->getObject(\"arguments\")) {");
+        push(@function, "    if (RefPtr<InspectorObject> paramsContainer = requestMessageObject->getObject(\"params\")) {");
 
         foreach my $parameter (@inArgs) {
             my $name = $parameter->name;
             my $type = $parameter->type;
             my $typeString = camelCase($parameter->type);
             my $optional = $parameter->extendedAttributes->{"optional"} ? "true" : "false";
-            push(@function, "        " . typeTraits($type, "variable") . " in_$name = get$typeString(argumentsContainer.get(), \"$name\", $optional, protocolErrors.get());");
+            push(@function, "        " . typeTraits($type, "variable") . " in_$name = get$typeString(paramsContainer.get(), \"$name\", $optional, protocolErrors.get());");
         }
         push(@function, "");
         $indent = "    ";
@@ -455,31 +461,30 @@ sub generateBackendFunction
     push(@function, "$indent    if (!protocolErrors->length())");
     push(@function, "$indent        $domainAccessor->$functionName($args);");
     if (scalar(@inArgs)) {
-        push(@function, "    } else {");
-        push(@function, "        protocolErrors->pushString(\"Protocol Error: 'arguments' property with type 'object' was not found.\");");
-        push(@function, "    }");
+        push(@function, "    } else");
+        push(@function, "        protocolErrors->pushString(\"'params' property with type 'object' was not found.\");");
     }
 
+    push(@function, "");
     push(@function, "    // use InspectorFrontend as a marker of WebInspector availability");
-    push(@function, "    if (callId || protocolErrors->length()) {");
-    push(@function, "        RefPtr<InspectorObject> responseMessage = InspectorObject::create();");
-    push(@function, "        responseMessage->setNumber(\"requestId\", callId);");
     push(@function, "");
-    push(@function, "        if (protocolErrors->length())");
-    push(@function, "            responseMessage->setArray(\"protocolErrors\", protocolErrors);");
-    if (scalar(@outArgs)) {
-        push(@function, "        else {");
-        push(@function, "            if (error.length())");
-        push(@function, "                responseMessage->setString(\"error\", error);");
-        push(@function, "            RefPtr<InspectorObject> responseBody = InspectorObject::create();");
-        push(@function, map("            responseBody->set" . typeTraits($_->type, "JSONType") . "(\"" . $_->name . "\", out_" . $_->name . ");", @outArgs));
-        push(@function, "            responseMessage->setObject(\"body\", responseBody);");
-        push(@function, "        }");
-    }
-    push(@function, "        m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());");
+    push(@function, "    if (protocolErrors->length()) {");
+    push(@function, "        reportProtocolError(callId, InvalidParams, protocolErrors);");
+    push(@function, "        return;");
     push(@function, "    }");
-
-
+    push(@function, "");
+    push(@function, "    if (error.length()) {");
+    push(@function, "        reportProtocolError(callId, ServerError, error);");
+    push(@function, "        return;");
+    push(@function, "    }");
+    push(@function, "");
+    push(@function, "    RefPtr<InspectorObject> responseMessage = InspectorObject::create();");
+    push(@function, "    RefPtr<InspectorObject> result = InspectorObject::create();");
+    push(@function, map("        result->set" . typeTraits($_->type, "JSONType") . "(\"" . $_->name . "\", out_" . $_->name . ");", @outArgs));
+    push(@function, "    responseMessage->setObject(\"result\", result);");
+    push(@function, "");
+    push(@function, "    responseMessage->setNumber(\"id\", callId);");
+    push(@function, "    m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());");
     push(@function, "}");
     push(@function, "");
     push(@backendMethodsImpl, @function);
@@ -489,13 +494,34 @@ sub generateBackendReportProtocolError
 {
     my $reportProtocolError = << "EOF";
 
-void ${backendClassName}::reportProtocolError(const long callId, const String& errorText) const
+void ${backendClassName}::reportProtocolError(const long callId, CommonErrorCode code, const String& customText) const
 {
+    RefPtr<InspectorArray> data = InspectorArray::create();
+    data->pushString(customText);
+    reportProtocolError(callId, code, data.release());
+}
+
+void ${backendClassName}::reportProtocolError(const long callId, CommonErrorCode code, PassRefPtr<InspectorArray> data) const
+{
+    DEFINE_STATIC_LOCAL(Vector<String>,s_commonErrors,);
+    if (!s_commonErrors.size()) {
+        s_commonErrors.insert(ParseError, "{\\\"code\\\":-32700,\\\"message\\\":\\\"Parse error.\\\"}");
+        s_commonErrors.insert(InvalidRequest, "{\\\"code\\\":-32600,\\\"message\\\":\\\"Invalid Request.\\\"}");
+        s_commonErrors.insert(MethodNotFound, "{\\\"code\\\":-32601,\\\"message\\\":\\\"Method not found.\\\"}");
+        s_commonErrors.insert(InvalidParams, "{\\\"code\\\":-32602,\\\"message\\\":\\\"Invalid params.\\\"}");
+        s_commonErrors.insert(InternalError, "{\\\"code\\\":-32603,\\\"message\\\":\\\"Internal error.\\\"}");
+        s_commonErrors.insert(ServerError, "{\\\"code\\\":-32000,\\\"message\\\":\\\"Server error.\\\"}");
+    }
+    ASSERT(code >=0);
+    ASSERT((unsigned)code < s_commonErrors.size());
+    ASSERT(s_commonErrors[code]);
+    ASSERT(InspectorObject::parseJSON(s_commonErrors[code]));
+    RefPtr<InspectorObject> error = InspectorObject::parseJSON(s_commonErrors[code])->asObject();
+    ASSERT(error);
+    error->setArray("data", data);
     RefPtr<InspectorObject> message = InspectorObject::create();
-    message->setNumber("requestId", callId);
-    RefPtr<InspectorArray> errors = InspectorArray::create();
-    errors->pushString(errorText);
-    message->setArray("protocolErrors", errors);
+    message->setObject("error", error);
+    message->setNumber("id", callId);
     m_inspectorFrontendChannel->sendMessageToFrontend(message->toJSONString());
 }
 EOF
@@ -525,12 +551,12 @@ $return InspectorBackendDispatcher::get$typeString(InspectorObject* object, cons
 
     if (valueIterator == end) {
         if (!optional)
-            protocolErrors->pushString(String::format("Protocol Error: Argument '\%s' with type '$json' was not found.", name.utf8().data()));
+            protocolErrors->pushString(String::format("Parameter '\%s' with type '$json' was not found.", name.utf8().data()));
         return value;
     }
 
     if (!valueIterator->second->as$json(&value))
-        protocolErrors->pushString(String::format("Protocol Error: Argument '\%s' has wrong type. It should be '$json'.", name.utf8().data()));
+        protocolErrors->pushString(String::format("Parameter '\%s' has wrong type. It should be '$json'.", name.utf8().data()));
     return value;
 }
 EOF
@@ -545,11 +571,6 @@ sub generateBackendDispatcher
     my $mapEntries = join("\n", @mapEntries);
 
     my $backendDispatcherBody = << "EOF";
-static String commandName(const String& domain, const String& command)
-{
-    return makeString(domain, "_", command);
-}
-
 void ${backendClassName}::dispatch(const String& message)
 {
     typedef void (${backendClassName}::*CallHandler)(long callId, InspectorObject* messageObject);
@@ -563,54 +584,42 @@ $mapEntries
 
     RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);
     if (!parsedMessage) {
-        reportProtocolError(callId, "Protocol Error: Invalid message format. Message should be in JSON format.");
+        reportProtocolError(callId, ParseError, "Message should be in JSON format.");
         return;
     }
 
     RefPtr<InspectorObject> messageObject = parsedMessage->asObject();
     if (!messageObject) {
-        reportProtocolError(callId, "Protocol Error: Invalid message format. The message should be a JSONified object.");
+        reportProtocolError(callId, InvalidRequest, "Invalid message format. The message should be a JSONified object.");
         return;
     }
 
-    RefPtr<InspectorValue> commandValue = messageObject->get("command");
-    if (!commandValue) {
-        reportProtocolError(callId, "Protocol Error: Invalid message format. 'command' property wasn't found.");
+    RefPtr<InspectorValue> methodValue = messageObject->get("method");
+    if (!methodValue) {
+        reportProtocolError(callId, InvalidRequest, "Invalid message format. 'method' property wasn't found.");
         return;
     }
 
-    String command;
-    if (!commandValue->asString(&command)) {
-        reportProtocolError(callId, "Protocol Error: Invalid message format. The type of 'command' property should be string.");
-        return;
-    }
-
-    RefPtr<InspectorValue> domainValue = messageObject->get("domain");
-    if (!domainValue) {
-        reportProtocolError(callId, "Protocol Error: Invalid message format. 'domain' property wasn't found.");
-        return;
-    }
-
-    String domain;
-    if (!domainValue->asString(&domain)) {
-        reportProtocolError(callId, "Protocol Error: Invalid message format. The type of 'domain' property should be string.");
+    String method;
+    if (!methodValue->asString(&method)) {
+        reportProtocolError(callId, InvalidRequest, "Invalid message format. The type of 'method' property should be string.");
         return;
     }
 
     RefPtr<InspectorValue> callIdValue = messageObject->get("id");
     if (!callIdValue) {
-        reportProtocolError(callId, "Protocol Error: Invalid message format. 'id' property was not found in the request.");
+        reportProtocolError(callId, InvalidRequest, "Invalid message format. 'id' property was not found in the request.");
         return;
     }
 
     if (!callIdValue->asNumber(&callId)) {
-        reportProtocolError(callId, "Protocol Error: Invalid message format. The type of 'id' property should be number.");
+        reportProtocolError(callId, InvalidRequest, "Invalid message format. The type of 'id' property should be number.");
         return;
     }
 
-    HashMap<String, CallHandler>::iterator it = dispatchMap.find(commandName(domain, command));
+    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
     if (it == dispatchMap.end()) {
-        reportProtocolError(callId, makeString("Protocol Error: Invalid command was received. '", command, "' wasn't found in domain ", domain, "."));
+        reportProtocolError(callId, MethodNotFound, makeString("Invalid method name was received. '", method, "' wasn't found."));
         return;
     }
 
@@ -633,15 +642,9 @@ bool ${backendClassName}::getCommandName(const String& message, String* result)
     if (!object)
         return false;
 
-    String domain;
-    if (!object->getString("domain", &domain))
+    if (!object->getString("method", result))
         return false;
 
-    String command;
-    if (!object->getString("command", &command))
-        return false;
-
-    *result = commandName(domain, command);
     return true;
 }
 EOF
@@ -656,18 +659,18 @@ sub collectBackendJSStubFunctions
 
     foreach my $function (@functions) {
         my $name = $function->signature->name;
+        my @inArgs = grep($_->direction eq "in", @{$function->parameters});
         my $argumentNames = join(
             ",",
             map("\"" . $_->name . "\": {"
                 . "\"optional\": " . ($_->extendedAttributes->{"optional"} ? "true " : "false") . ", "
                 . "\"type\": \"" . typeTraits($_->type, "JSType") . "\""
                 . "}",
-                grep($_->direction eq "in", @{$function->parameters})));
+                 @inArgs));
         push(@backendJSStubs, "    this._registerDelegate('{" .
-            "\"id\": 0, " .
-            "\"domain\": \"$domain\", " .
-            "\"command\": \"$name\", " .
-            "\"arguments\": {$argumentNames}" .
+            "\"method\": \"$domain.$name\", " .
+            (scalar(@inArgs) ? "\"params\": {$argumentNames}, " : "") .
+            "\"id\": 0" .
         "}');");
     }
 }
@@ -695,13 +698,13 @@ InspectorBackendStub.prototype = {
         return callbackId;
     },
 
-    _registerDelegate: function(commandInfo)
+    _registerDelegate: function(requestString)
     {
-        var commandObject = JSON.parse(commandInfo);
-        var agentName = commandObject.domain + "Agent";
+        var domainAndFunction = JSON.parse(requestString).method.split(".");
+        var agentName = domainAndFunction[0] + "Agent";
         if (!window[agentName])
             window[agentName] = {};
-        window[agentName][commandObject.command] = this.sendMessageToBackend.bind(this, commandInfo);
+        window[agentName][domainAndFunction[1]] = this.sendMessageToBackend.bind(this, requestString);
     },
 
     sendMessageToBackend: function()
@@ -709,33 +712,37 @@ InspectorBackendStub.prototype = {
         var args = Array.prototype.slice.call(arguments);
         var request = JSON.parse(args.shift());
         var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : 0;
+        var domainAndMethod = request.method.split(".");
+        var agentMethod = domainAndMethod[0] + "Agent." + domainAndMethod[1];
 
-        for (var key in request.arguments) {
-            var typeName = request.arguments[key].type;
-            var optionalFlag = request.arguments[key].optional;
+        if (request.params) {
+            for (var key in request.params) {
+                var typeName = request.params[key].type;
+                var optionalFlag = request.params[key].optional;
 
-            if (args.length === 0 && !optionalFlag) {
-                console.error("Protocol Error: Invalid number of arguments for '" + request.domain + "Agent." + request.command + "' call. It should have the next arguments '" + JSON.stringify(request.arguments) + "'.");
-                return;
-            }
+                if (args.length === 0 && !optionalFlag) {
+                    console.error("Protocol Error: Invalid number of arguments for method '" + agentMethod + "' call. It should have the next arguments '" + JSON.stringify(request.params) + "'.");
+                    return;
+                }
 
-            var value = args.shift();
-            if (optionalFlag && typeof value === "undefined") {
-                delete request.arguments[key];
-                continue;
-            }
+                var value = args.shift();
+                if (optionalFlag && typeof value === "undefined") {
+                    delete request.params[key];
+                    continue;
+                }
 
-            if (typeof value !== typeName) {
-                console.error("Protocol Error: Invalid type of argument '" + key + "' for '" + request.domain + "Agent." + request.command + "' call. It should be '" + typeName + "' but it is '" + typeof value + "'.");
-                return;
-            }
+                if (typeof value !== typeName) {
+                    console.error("Protocol Error: Invalid type of argument '" + key + "' for method '" + agentMethod + "' call. It should be '" + typeName + "' but it is '" + typeof value + "'.");
+                    return;
+                }
 
-            request.arguments[key] = value;
+                request.params[key] = value;
+            }
         }
 
         if (args.length === 1 && !callback) {
             if (typeof args[0] !== "undefined") {
-                console.error("Protocol Error: Optional callback argument for '" + request.domain + "Agent." + request.command + "' call should be a function but its type is '" + typeof args[0] + "'.");
+                console.error("Protocol Error: Optional callback argument for method '" + agentMethod + "' call should be a function but its type is '" + typeof args[0] + "'.");
                 return;
             }
         }
@@ -762,58 +769,58 @@ InspectorBackendStub.prototype = {
 
         var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
 
-        if ("requestId" in messageObject) { // just a response for some request
-            if (messageObject.protocolErrors)
+        if ("id" in messageObject) { // just a response for some request
+            if (messageObject.error && messageObject.error.code !== -32000)
                 this.reportProtocolError(messageObject);
 
             var arguments = [];
-            if (messageObject.body) {
-                for (var key in messageObject.body)
-                    arguments.push(messageObject.body[key]);
+            if (messageObject.result) {
+                for (var key in messageObject.result)
+                    arguments.push(messageObject.result[key]);
             }
 
-            var callback = this._callbacks[messageObject.requestId];
+            var callback = this._callbacks[messageObject.id];
             if (callback) {
-                if (!messageObject.protocolErrors) {
-                    arguments.unshift(messageObject.error);
-                    callback.apply(null, arguments);
-                }
+                arguments.unshift(messageObject.error);
+                callback.apply(null, arguments);
                 --this._pendingResponsesCount;
-                delete this._callbacks[messageObject.requestId];
+                delete this._callbacks[messageObject.id];
             }
 
             if (this._scripts && !this._pendingResponsesCount)
                 this.runAfterPendingDispatches();
 
             return;
-        }
-
-        if (messageObject.type === "event") {
-            if (!(messageObject.domain in this._domainDispatchers)) {
-                console.error("Protocol Error: the message is for non-existing domain '" + messageObject.domain + "'");
+        } else {
+            var method = messageObject.method.split(".");
+            var domainName = method[0];
+            var functionName = method[1];
+            if (!(domainName in this._domainDispatchers)) {
+                console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
                 return;
             }
-            var dispatcher = this._domainDispatchers[messageObject.domain];
-            if (!(messageObject.event in dispatcher)) {
-                console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.domain + "." + messageObject.event + "'");
+            var dispatcher = this._domainDispatchers[domainName];
+            if (!(functionName in dispatcher)) {
+                console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
                 return;
             }
 
-            var arguments = [];
-            if (messageObject.data) {
-                for (var key in messageObject.data)
-                    arguments.push(messageObject.data[key]);
+            var params = [];
+            if (messageObject.params) {
+                for (var key in messageObject.params)
+                    params.push(messageObject.params[key]);
             }
 
-            dispatcher[messageObject.event].apply(dispatcher, arguments);
+            dispatcher[functionName].apply(dispatcher, params);
         }
     },
 
     reportProtocolError: function(messageObject)
     {
-        console.error("Protocol Error: InspectorBackend request with id = " + messageObject.requestId + " failed.");
-        for (var i = 0; i < messageObject.protocolErrors.length; ++i)
-            console.error("    " + messageObject.protocolErrors[i]);
+        var error = messageObject.error;
+        console.error(error.message + "(" + error.code + "): request with id = " + messageObject.id + " failed.");
+        for (var i = 0; i < error.data.length; ++i)
+            console.error("    " + error.data[i]);
     },
 
     runAfterPendingDispatches: function(script)
@@ -954,7 +961,19 @@ sub generateBackendAgentFieldsAndConstructor
     push(@backendHead, "    ${backendClassName}(${argumentString})");
     push(@backendHead, @fieldInitializers);
     push(@backendHead, "    { }");
-    push(@backendHead, "    void reportProtocolError(const long callId, const String& errorText) const;");
+    push(@backendHead, "");
+    push(@backendHead, "    enum CommonErrorCode {");
+    push(@backendHead, "        ParseError = 0,");
+    push(@backendHead, "        InvalidRequest,");
+    push(@backendHead, "        MethodNotFound,");
+    push(@backendHead, "        InvalidParams,");
+    push(@backendHead, "        InternalError,");
+    push(@backendHead, "        ServerError,");
+    push(@backendHead, "        LastEntry,");
+    push(@backendHead, "    };");
+    push(@backendHead, "");
+    push(@backendHead, "    void reportProtocolError(const long callId, CommonErrorCode, const String& errorText) const;");
+    push(@backendHead, "    void reportProtocolError(const long callId, CommonErrorCode, PassRefPtr<InspectorArray> data) const;");
     push(@backendHead, "    void dispatch(const String& message);");
     push(@backendHead, "    static bool getCommandName(const String& message, String* result);");
     $backendConstructor = join("\n", @backendHead);