Enable geolocation client based flag for Qt5
[WebKit-https.git] / Source / WebCore / inspector / CodeGeneratorInspector.py
1 #!/usr/bin/env python
2 # Copyright (c) 2011 Google Inc. All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 #     * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 #     * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
13 # distribution.
14 #     * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 import os.path
31 import sys
32 import string
33 import optparse
34 import json
35 from string import join
36
37 cmdline_parser = optparse.OptionParser()
38 cmdline_parser.add_option("--defines")
39 cmdline_parser.add_option("--output_h_dir")
40 cmdline_parser.add_option("--output_cpp_dir")
41
42 try:
43     arg_options, arg_values = cmdline_parser.parse_args()
44     if (len(arg_values) != 1):
45         raise Exception("Exactly one plain argument expected (found %s)" % len(arg_values))
46     input_json_filename = arg_values[0]
47     output_header_dirname = arg_options.output_h_dir
48     output_cpp_dirname = arg_options.output_cpp_dir
49     if not output_header_dirname:
50         raise Exception("Output .h directory must be specified")
51     if not output_cpp_dirname:
52         raise Exception("Output .cpp directory must be specified")
53 except Exception, e:
54     sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % e)
55     sys.stderr.write("Usage: <script> Inspector.json --output_h_dir <output_header_dir> --output_cpp_dir <output_cpp_dir> [--defines <defines string>]\n")
56     exit(1)
57
58
59 def parse_defines(str):
60     if not str:
61         return {}
62
63     items = str.split()
64     result = {}
65     for item in items:
66         if item[0] == '"' and item[-1] == '"' and len(item) >= 2:
67             item = item[1:-1]
68         eq_pos = item.find("=")
69         if eq_pos == -1:
70             key = item
71             value = True
72         else:
73             key = item[:eq_pos]
74             value_str = item[eq_pos + 1:]
75             if value_str == "0":
76                 value = False
77             elif value_str == "1":
78                 value = True
79             else:
80                 # Should we support other values?
81                 raise Exception("Unrecognized define value: '%s' (key: '%s')" % (value_str, key))
82         result[key] = value
83     return result
84
85 defines_map = parse_defines(arg_options.defines)
86
87
88 class DomainNameFixes:
89     @classmethod
90     def get_fixed_data(cls, domain_name):
91         if domain_name in cls.agent_type_map:
92             agent_name_res = cls.agent_type_map[domain_name]
93         else:
94             agent_name_res = "Inspector%sAgent" % domain_name
95
96         if domain_name in cls.agent_field_name_map:
97             field_name_res = cls.agent_field_name_map[domain_name]
98         else:
99             field_name_res = domain_name.lower() + "Agent"
100
101         class Res(object):
102             agent_type_name = agent_name_res
103             hidden = domain_name in cls.hidden_domains
104             skip_js_bind = domain_name in cls.skip_js_bind_domains
105             agent_field_name = field_name_res
106
107             @staticmethod
108             def is_disabled(defines):
109                 if not domain_name in cls.domain_define_name_map:
110                     # Has not corresponding preprocessor symbol.
111                     return False
112
113                 define_name = cls.domain_define_name_map[domain_name]
114
115                 if not define_name in defines:
116                     # Disabled when not mentioned
117                     return True
118
119                 define_value = defines[define_name]
120                 return not bool(define_value)
121
122         return Res
123
124     skip_js_bind_domains = set(["Runtime", "CSS", "DOMDebugger"])
125     hidden_domains = set(["Inspector"])
126     agent_type_map = {"Network": "InspectorResourceAgent"}
127
128     # TODO: get rid of this, generate names instead.
129     agent_field_name_map = {
130         "Page": "pageAgent",
131         "Runtime": "runtimeAgent",
132         "Console": "consoleAgent",
133         "Network":  "resourceAgent",
134         "Database":  "databaseAgent",
135         "DOMStorage":  "domStorageAgent",
136         "ApplicationCache":  "applicationCacheAgent",
137         "DOM":  "domAgent",
138         "CSS":  "cssAgent",
139         "Debugger": "debuggerAgent",
140         "DOMDebugger": "domDebuggerAgent",
141         "Profiler": "profilerAgent",
142         "Worker": "workerAgent",
143     }
144
145     domain_define_name_map = {
146         "Database": "ENABLE_SQL_DATABASE",
147         "Debugger": "ENABLE_JAVASCRIPT_DEBUGGER",
148         "DOMDebugger": "ENABLE_JAVASCRIPT_DEBUGGER",
149         "Profiler": "ENABLE_JAVASCRIPT_DEBUGGER",
150         "Worker": "ENABLE_WORKERS",
151     }
152
153
154 class CParamType(object):
155     def __init__(self, type, setter_format="%s"):
156         self.type = type
157         self.setter_format = setter_format
158
159     def get_text(self):
160         return self.type
161
162     def get_setter_format(self):
163         return self.setter_format
164
165
166 class RawTypes(object):
167     @staticmethod
168     def get(json_type):
169         if json_type == "boolean":
170             return RawTypes.Bool
171         elif json_type == "string":
172             return RawTypes.String
173         elif json_type == "array":
174             return RawTypes.Array
175         elif json_type == "object":
176             return RawTypes.Object
177         elif json_type == "integer":
178             return RawTypes.Int
179         elif json_type == "number":
180             return RawTypes.Number
181         else:
182             raise Exception("Unknown type: %s" % json_type)
183
184     class BaseType(object):
185         @classmethod
186         def get_c_param_type(cls, param_type, optional):
187             return cls.default_c_param_type
188
189         @staticmethod
190         def is_event_param_check_optional():
191             return False
192
193     class String(BaseType):
194         @classmethod
195         def get_c_param_type(cls, param_type, optional):
196             if param_type == ParamType.EVENT:
197                 return cls._ref_c_type
198             else:
199                 return cls._plain_c_type
200
201         @staticmethod
202         def get_getter_name():
203             return "String"
204
205         get_setter_name = get_getter_name
206
207         @staticmethod
208         def get_c_initializer():
209             return "\"\""
210
211         @staticmethod
212         def get_js_bind_type():
213             return "string"
214
215         _plain_c_type = CParamType("String")
216         _ref_c_type = CParamType("const String&")
217
218     class Int(BaseType):
219         @staticmethod
220         def get_getter_name():
221             return "Int"
222
223         @staticmethod
224         def get_setter_name():
225             return "Number"
226
227         @staticmethod
228         def get_c_initializer():
229             return "0"
230
231         @staticmethod
232         def get_js_bind_type():
233             return "number"
234
235         default_c_param_type = CParamType("int")
236
237     class Number(BaseType):
238         @staticmethod
239         def get_getter_name():
240             return "Object"
241
242         @staticmethod
243         def get_setter_name():
244             return "Number"
245
246         @staticmethod
247         def get_c_initializer():
248             raise Exception("Unsupported")
249
250         @staticmethod
251         def get_js_bind_type():
252             raise Exception("Unsupported")
253
254         default_c_param_type = CParamType("double")
255
256     class Bool(BaseType):
257         @classmethod
258         def get_c_param_type(cls, param_type, optional):
259             if (param_type == ParamType.EVENT):
260                 if optional:
261                     return cls._ref_c_type
262                 else:
263                     return cls._plain_c_type
264             else:
265                 return cls._plain_c_type
266
267         @staticmethod
268         def get_getter_name():
269             return "Boolean"
270
271         get_setter_name = get_getter_name
272
273         @staticmethod
274         def get_c_initializer():
275             return "false"
276
277         @staticmethod
278         def get_js_bind_type():
279             return "boolean"
280
281         @staticmethod
282         def is_event_param_check_optional():
283             return True
284
285         _plain_c_type = CParamType("bool")
286         _ref_c_type = CParamType("const bool* const", "*%s")
287
288     class Object(BaseType):
289         @classmethod
290         def get_c_param_type(cls, param_type, optional):
291             if param_type == ParamType.EVENT:
292                 return cls._ref_c_type
293             else:
294                 return cls._plain_c_type
295
296         @staticmethod
297         def get_getter_name():
298             return "Object"
299
300         get_setter_name = get_getter_name
301
302         @staticmethod
303         def get_c_initializer():
304             return "InspectorObject::create()"
305
306         @staticmethod
307         def get_js_bind_type():
308             return "object"
309
310         @staticmethod
311         def is_event_param_check_optional():
312             return True
313
314         _plain_c_type = CParamType("RefPtr<InspectorObject>")
315         _ref_c_type = CParamType("PassRefPtr<InspectorObject>")
316
317     class Array(BaseType):
318         @classmethod
319         def get_c_param_type(cls, param_type, optional):
320             if param_type == ParamType.OUTPUT:
321                 return cls._plain_c_type
322             elif param_type == ParamType.INPUT:
323                 return cls._plain_c_type
324             else:
325                 return cls._ref_c_type
326
327         @staticmethod
328         def get_getter_name():
329             return "Array"
330
331         get_setter_name = get_getter_name
332
333         @staticmethod
334         def get_c_initializer():
335             return "InspectorArray::create()"
336
337         @staticmethod
338         def get_js_bind_type():
339             return "object"
340
341         @staticmethod
342         def is_event_param_check_optional():
343             return True
344
345         _plain_c_type = CParamType("RefPtr<InspectorArray>")
346         _ref_c_type = CParamType("PassRefPtr<InspectorArray>")
347
348
349 class ParamType(object):
350     INPUT = "input"
351     OUTPUT = "output"
352     EVENT = "event"
353
354
355 class TypeData(object):
356     def __init__(self, json_type, json_domain):
357         self.json_type_ = json_type
358         self.json_domain_ = json_domain
359
360         if "type" in json_type:
361             json_type_name = json_type["type"]
362             raw_type = RawTypes.get(json_type_name)
363         else:
364             raise Exception("Unknown type")
365         self.raw_type_ = raw_type
366
367     def get_raw_type(self):
368         return self.raw_type_
369
370
371 class TypeMap:
372     def __init__(self, api):
373         self.map_ = {}
374         for json_domain in api["domains"]:
375             domain_name = json_domain["domain"]
376
377             domain_map = {}
378             self.map_[domain_name] = domain_map
379
380             if "types" in json_domain:
381                 for json_type in json_domain["types"]:
382                     type_name = json_type["id"]
383                     type_data = TypeData(json_type, json_domain)
384                     domain_map[type_name] = type_data
385
386     def get(self, domain_name, type_name):
387         return self.map_[domain_name][type_name]
388
389
390 def resolve_param_raw_type(json_parameter, scope_domain_name):
391     if "$ref" in json_parameter:
392         json_ref = json_parameter["$ref"]
393         type_data = get_ref_data(json_ref, scope_domain_name)
394         return type_data.get_raw_type()
395     elif "type" in json_parameter:
396         json_type = json_parameter["type"]
397         return RawTypes.get(json_type)
398     else:
399         raise Exception("Unknown type")
400
401
402 def get_ref_data(json_ref, scope_domain_name):
403     dot_pos = json_ref.find(".")
404     if dot_pos == -1:
405         domain_name = scope_domain_name
406         type_name = json_ref
407     else:
408         domain_name = json_ref[:dot_pos]
409         type_name = json_ref[dot_pos + 1:]
410
411     return type_map.get(domain_name, type_name)
412
413
414 input_file = open(input_json_filename, "r")
415 json_string = input_file.read()
416 json_api = json.loads(json_string)
417
418
419 class Templates:
420     frontend_domain_class = string.Template(
421 """    class $domainClassName {
422     public:
423         $domainClassName(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }
424 ${frontendDomainMethodDeclarations}        void setInspectorFrontendChannel(InspectorFrontendChannel* inspectorFrontendChannel) { m_inspectorFrontendChannel = inspectorFrontendChannel; }
425         InspectorFrontendChannel* getInspectorFrontendChannel() { return m_inspectorFrontendChannel; }
426     private:
427         InspectorFrontendChannel* m_inspectorFrontendChannel;
428     };
429
430     $domainClassName* $domainFieldName() { return &m_$domainFieldName; }
431
432 """)
433
434     backend_method = string.Template(
435 """void InspectorBackendDispatcher::${domainName}_$methodName(long callId, InspectorObject*$requestMessageObject)
436 {
437     RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
438
439     if (!$agentField)
440         protocolErrors->pushString("${domainName} handler is not available.");
441 $methodOutCode
442     ErrorString error;
443 $methodInCode
444 if (!protocolErrors->length())
445     $agentField->$methodName(&error$agentCallParams);
446
447     RefPtr<InspectorObject> result = InspectorObject::create();
448 ${responseCook}sendResponse(callId, result, String::format("Some arguments of method '%s' can't be processed", "$domainName.$methodName"), protocolErrors, error);
449 }
450 """)
451
452     frontend_method = string.Template("""void InspectorFrontend::$domainName::$eventName($parameters)
453 {
454     RefPtr<InspectorObject> ${eventName}Message = InspectorObject::create();
455     ${eventName}Message->setString("method", "$domainName.$eventName");
456 $code    if (m_inspectorFrontendChannel)
457         m_inspectorFrontendChannel->sendMessageToFrontend(${eventName}Message->toJSONString());
458 }
459 """)
460
461     frontend_h = string.Template("""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
462 // Use of this source code is governed by a BSD-style license that can be
463 // found in the LICENSE file.
464 #ifndef InspectorFrontend_h
465 #define InspectorFrontend_h
466
467 #include <PlatformString.h>
468 #include <wtf/PassRefPtr.h>
469
470 namespace WebCore {
471
472 class InspectorArray;
473 class InspectorFrontendChannel;
474 class InspectorObject;
475
476 typedef String ErrorString;
477
478 class InspectorFrontend {
479 public:
480     InspectorFrontend(InspectorFrontendChannel*);
481
482
483 $domainClassList
484 private:
485     InspectorFrontendChannel* m_inspectorFrontendChannel;
486 ${fieldDeclarations}};
487
488 } // namespace WebCore
489 #endif // !defined(InspectorFrontend_h)
490 """)
491
492     backend_h = string.Template("""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
493 // Use of this source code is governed by a BSD-style license that can be
494 // found in the LICENSE file.
495 #ifndef InspectorBackendDispatcher_h
496 #define InspectorBackendDispatcher_h
497
498 #include <PlatformString.h>
499 #include <wtf/PassRefPtr.h>
500 #include <wtf/RefCounted.h>
501
502 namespace WebCore {
503
504 class InspectorAgent;
505 class InspectorObject;
506 class InspectorArray;
507 class InspectorFrontendChannel;
508
509 $forwardDeclarations
510
511 typedef String ErrorString;
512
513 class InspectorBackendDispatcher: public RefCounted<InspectorBackendDispatcher> {
514 public:
515     InspectorBackendDispatcher(InspectorFrontendChannel* inspectorFrontendChannel$constructorParams)
516         : m_inspectorFrontendChannel(inspectorFrontendChannel)
517 $constructorInit
518     { }
519
520     void clearFrontend() { m_inspectorFrontendChannel = 0; }
521
522     enum CommonErrorCode {
523         ParseError = 0,
524         InvalidRequest,
525         MethodNotFound,
526         InvalidParams,
527         InternalError,
528         ServerError,
529         LastEntry,
530     };
531
532     void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage) const;
533     void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<InspectorArray> data) const;
534     void dispatch(const String& message);
535     static bool getCommandName(const String& message, String* result);
536
537     enum MethodNames {
538
539 $methodNamesEnumContent
540 };
541
542     static const char* commandNames[];
543
544 private:
545     static int getInt(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
546     static String getString(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
547     static bool getBoolean(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
548     static PassRefPtr<InspectorObject> getObject(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
549     static PassRefPtr<InspectorArray> getArray(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
550     void sendResponse(long callId, PassRefPtr<InspectorObject> result, const String& errorMessage, PassRefPtr<InspectorArray> protocolErrors, ErrorString invocationError);
551
552 $methodDeclarations
553
554     InspectorFrontendChannel* m_inspectorFrontendChannel;
555 $fieldDeclarations
556 };
557
558 } // namespace WebCore
559 #endif // !defined(InspectorBackendDispatcher_h)
560
561
562 """)
563
564     backend_cpp = string.Template("""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
565 // Use of this source code is governed by a BSD-style license that can be
566 // found in the LICENSE file.
567
568
569 #include "config.h"
570 #include "InspectorBackendDispatcher.h"
571 #include <wtf/text/WTFString.h>
572 #include <wtf/text/CString.h>
573
574 #if ENABLE(INSPECTOR)
575
576 #include "InspectorAgent.h"
577 #include "InspectorValues.h"
578 #include "PlatformString.h"
579 #include "InspectorFrontendChannel.h"
580 $includes
581
582 namespace WebCore {
583
584 const char* InspectorBackendDispatcher::commandNames[] = {
585 $methodNameDeclarations
586 };
587
588
589 $methods
590 void InspectorBackendDispatcher::dispatch(const String& message)
591 {
592     RefPtr<InspectorBackendDispatcher> protect = this;
593     typedef void (InspectorBackendDispatcher::*CallHandler)(long callId, InspectorObject* messageObject);
594     typedef HashMap<String, CallHandler> DispatchMap;
595     DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, );
596     long callId = 0;
597
598     if (dispatchMap.isEmpty()) {
599         static CallHandler handlers[] = {
600 $messageHandlers
601         };
602         size_t length = sizeof(commandNames) / sizeof(commandNames[0]);
603         for (size_t i = 0; i < length; ++i)
604             dispatchMap.add(commandNames[i], handlers[i]);
605     }
606
607     RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);
608     if (!parsedMessage) {
609         reportProtocolError(0, ParseError, "Message must be in JSON format");
610         return;
611     }
612
613     RefPtr<InspectorObject> messageObject = parsedMessage->asObject();
614     if (!messageObject) {
615         reportProtocolError(0, InvalidRequest, "Message must be a JSONified object");
616         return;
617     }
618
619     RefPtr<InspectorValue> callIdValue = messageObject->get("id");
620     if (!callIdValue) {
621         reportProtocolError(0, InvalidRequest, "'id' property was not found");
622         return;
623     }
624
625     if (!callIdValue->asNumber(&callId)) {
626         reportProtocolError(0, InvalidRequest, "The type of 'id' property must be number");
627         return;
628     }
629
630     RefPtr<InspectorValue> methodValue = messageObject->get("method");
631     if (!methodValue) {
632         reportProtocolError(&callId, InvalidRequest, "'method' property wasn't found");
633         return;
634     }
635
636     String method;
637     if (!methodValue->asString(&method)) {
638         reportProtocolError(&callId, InvalidRequest, "The type of 'method' property must be string");
639         return;
640     }
641
642     HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
643     if (it == dispatchMap.end()) {
644         reportProtocolError(&callId, MethodNotFound, "'" + method + "' wasn't found");
645         return;
646     }
647
648     ((*this).*it->second)(callId, messageObject.get());
649 }
650
651 void InspectorBackendDispatcher::sendResponse(long callId, PassRefPtr<InspectorObject> result, const String& errorMessage, PassRefPtr<InspectorArray> protocolErrors, ErrorString invocationError)
652 {
653     if (protocolErrors->length()) {
654         reportProtocolError(&callId, InvalidParams, errorMessage, protocolErrors);
655         return;
656     }
657     if (invocationError.length()) {
658         reportProtocolError(&callId, ServerError, invocationError);
659         return;
660     }
661
662     RefPtr<InspectorObject> responseMessage = InspectorObject::create();
663     responseMessage->setObject("result", result);
664     responseMessage->setNumber("id", callId);
665     if (m_inspectorFrontendChannel)
666         m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
667 }
668
669 void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage) const
670 {
671     reportProtocolError(callId, code, errorMessage, 0);
672 }
673
674 void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage, PassRefPtr<InspectorArray> data) const
675 {
676     DEFINE_STATIC_LOCAL(Vector<int>,s_commonErrors,);
677     if (!s_commonErrors.size()) {
678         s_commonErrors.insert(ParseError, -32700);
679         s_commonErrors.insert(InvalidRequest, -32600);
680         s_commonErrors.insert(MethodNotFound, -32601);
681         s_commonErrors.insert(InvalidParams, -32602);
682         s_commonErrors.insert(InternalError, -32603);
683         s_commonErrors.insert(ServerError, -32000);
684     }
685     ASSERT(code >=0);
686     ASSERT((unsigned)code < s_commonErrors.size());
687     ASSERT(s_commonErrors[code]);
688     RefPtr<InspectorObject> error = InspectorObject::create();
689     error->setNumber("code", s_commonErrors[code]);
690     error->setString("message", errorMessage);
691     ASSERT(error);
692     if (data)
693         error->setArray("data", data);
694     RefPtr<InspectorObject> message = InspectorObject::create();
695     message->setObject("error", error);
696     if (callId)
697         message->setNumber("id", *callId);
698     else
699         message->setValue("id", InspectorValue::null());
700     if (m_inspectorFrontendChannel)
701         m_inspectorFrontendChannel->sendMessageToFrontend(message->toJSONString());
702 }
703
704 int InspectorBackendDispatcher::getInt(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
705 {
706     ASSERT(protocolErrors);
707
708     if (valueFound)
709         *valueFound = false;
710
711     int value = 0;
712
713     if (!object) {
714         if (!valueFound) {
715             // Required parameter in missing params container.
716             protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'Number'.", name.utf8().data()));
717         }
718         return value;
719     }
720
721     InspectorObject::const_iterator end = object->end();
722     InspectorObject::const_iterator valueIterator = object->find(name);
723
724     if (valueIterator == end) {
725         if (!valueFound)
726             protocolErrors->pushString(String::format("Parameter '%s' with type 'Number' was not found.", name.utf8().data()));
727         return value;
728     }
729
730     if (!valueIterator->second->asNumber(&value))
731         protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'Number'.", name.utf8().data()));
732     else
733         if (valueFound)
734             *valueFound = true;
735     return value;
736 }
737
738 String InspectorBackendDispatcher::getString(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
739 {
740     ASSERT(protocolErrors);
741
742     if (valueFound)
743         *valueFound = false;
744
745     String value = "";
746
747     if (!object) {
748         if (!valueFound) {
749             // Required parameter in missing params container.
750             protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'String'.", name.utf8().data()));
751         }
752         return value;
753     }
754
755     InspectorObject::const_iterator end = object->end();
756     InspectorObject::const_iterator valueIterator = object->find(name);
757
758     if (valueIterator == end) {
759         if (!valueFound)
760             protocolErrors->pushString(String::format("Parameter '%s' with type 'String' was not found.", name.utf8().data()));
761         return value;
762     }
763
764     if (!valueIterator->second->asString(&value))
765         protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'String'.", name.utf8().data()));
766     else
767         if (valueFound)
768             *valueFound = true;
769     return value;
770 }
771
772 bool InspectorBackendDispatcher::getBoolean(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
773 {
774     ASSERT(protocolErrors);
775
776     if (valueFound)
777         *valueFound = false;
778
779     bool value = false;
780
781     if (!object) {
782         if (!valueFound) {
783             // Required parameter in missing params container.
784             protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'Boolean'.", name.utf8().data()));
785         }
786         return value;
787     }
788
789     InspectorObject::const_iterator end = object->end();
790     InspectorObject::const_iterator valueIterator = object->find(name);
791
792     if (valueIterator == end) {
793         if (!valueFound)
794             protocolErrors->pushString(String::format("Parameter '%s' with type 'Boolean' was not found.", name.utf8().data()));
795         return value;
796     }
797
798     if (!valueIterator->second->asBoolean(&value))
799         protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'Boolean'.", name.utf8().data()));
800     else
801         if (valueFound)
802             *valueFound = true;
803     return value;
804 }
805
806 PassRefPtr<InspectorObject> InspectorBackendDispatcher::getObject(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
807 {
808     ASSERT(protocolErrors);
809
810     if (valueFound)
811         *valueFound = false;
812
813     RefPtr<InspectorObject> value = InspectorObject::create();
814
815     if (!object) {
816         if (!valueFound) {
817             // Required parameter in missing params container.
818             protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'Object'.", name.utf8().data()));
819         }
820         return value;
821     }
822
823     InspectorObject::const_iterator end = object->end();
824     InspectorObject::const_iterator valueIterator = object->find(name);
825
826     if (valueIterator == end) {
827         if (!valueFound)
828             protocolErrors->pushString(String::format("Parameter '%s' with type 'Object' was not found.", name.utf8().data()));
829         return value;
830     }
831
832     if (!valueIterator->second->asObject(&value))
833         protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'Object'.", name.utf8().data()));
834     else
835         if (valueFound)
836             *valueFound = true;
837     return value;
838 }
839
840 PassRefPtr<InspectorArray> InspectorBackendDispatcher::getArray(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
841 {
842     ASSERT(protocolErrors);
843
844     if (valueFound)
845         *valueFound = false;
846
847     RefPtr<InspectorArray> value = InspectorArray::create();
848
849     if (!object) {
850         if (!valueFound) {
851             // Required parameter in missing params container.
852             protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'Array'.", name.utf8().data()));
853         }
854         return value;
855     }
856
857     InspectorObject::const_iterator end = object->end();
858     InspectorObject::const_iterator valueIterator = object->find(name);
859
860     if (valueIterator == end) {
861         if (!valueFound)
862             protocolErrors->pushString(String::format("Parameter '%s' with type 'Array' was not found.", name.utf8().data()));
863         return value;
864     }
865
866     if (!valueIterator->second->asArray(&value))
867         protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'Array'.", name.utf8().data()));
868     else
869         if (valueFound)
870             *valueFound = true;
871     return value;
872 }
873 bool InspectorBackendDispatcher::getCommandName(const String& message, String* result)
874 {
875     RefPtr<InspectorValue> value = InspectorValue::parseJSON(message);
876     if (!value)
877         return false;
878
879     RefPtr<InspectorObject> object = value->asObject();
880     if (!object)
881         return false;
882
883     if (!object->getString("method", result))
884         return false;
885
886     return true;
887 }
888
889
890 } // namespace WebCore
891
892 #endif // ENABLE(INSPECTOR)
893 """)
894
895     frontend_cpp = string.Template("""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
896 // Use of this source code is governed by a BSD-style license that can be
897 // found in the LICENSE file.
898
899
900 #include "config.h"
901 #include "InspectorFrontend.h"
902 #include <wtf/text/WTFString.h>
903 #include <wtf/text/CString.h>
904
905 #if ENABLE(INSPECTOR)
906
907 #include "InspectorFrontendChannel.h"
908 #include "InspectorValues.h"
909 #include "PlatformString.h"
910
911 namespace WebCore {
912
913
914
915 InspectorFrontend::InspectorFrontend(InspectorFrontendChannel* inspectorFrontendChannel)
916     : m_inspectorFrontendChannel(inspectorFrontendChannel)
917 $constructorInit{
918 }
919
920 $methods
921
922 } // namespace WebCore
923
924 #endif // ENABLE(INSPECTOR)
925 """)
926
927     backend_js = string.Template("""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
928 // Use of this source code is governed by a BSD-style license that can be
929 // found in the LICENSE file.
930
931
932 InspectorBackendStub = function()
933 {
934     this._lastCallbackId = 1;
935     this._pendingResponsesCount = 0;
936     this._callbacks = {};
937     this._domainDispatchers = {};
938     this._eventArgs = {};
939 $delegates$eventArgs$domainDispatchers    }
940
941 InspectorBackendStub.prototype = {
942     dumpInspectorTimeStats: 0,
943     dumpInspectorProtocolMessages: 0,
944
945     _wrap: function(callback)
946     {
947         var callbackId = this._lastCallbackId++;
948         this._callbacks[callbackId] = callback || function() {};
949         return callbackId;
950     },
951
952     _registerDelegate: function(requestString)
953     {
954         var domainAndFunction = JSON.parse(requestString).method.split(".");
955         var agentName = domainAndFunction[0] + "Agent";
956         if (!window[agentName])
957             window[agentName] = {};
958         window[agentName][domainAndFunction[1]] = this._sendMessageToBackend.bind(this, requestString);
959         window[agentName][domainAndFunction[1]]["invoke"] = this._invoke.bind(this, requestString)
960     },
961
962     _invoke: function(requestString, args, callback)
963     {
964         var request = JSON.parse(requestString);
965         request.params = args;
966         this._wrapCallbackAndSendMessageObject(request, callback);
967     },
968
969     _sendMessageToBackend: function()
970     {
971         var args = Array.prototype.slice.call(arguments);
972         var request = JSON.parse(args.shift());
973         var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : 0;
974         var domainAndMethod = request.method.split(".");
975         var agentMethod = domainAndMethod[0] + "Agent." + domainAndMethod[1];
976
977         var hasParams = false;
978         if (request.params) {
979             for (var key in request.params) {
980                 var typeName = request.params[key].type;
981                 var optionalFlag = request.params[key].optional;
982
983                 if (args.length === 0 && !optionalFlag) {
984                     console.error("Protocol Error: Invalid number of arguments for method '" + agentMethod + "' call. It must have the next arguments '" + JSON.stringify(request.params) + "'.");
985                     return;
986                 }
987
988                 var value = args.shift();
989                 if (optionalFlag && typeof value === "undefined") {
990                     delete request.params[key];
991                     continue;
992                 }
993
994                 if (typeof value !== typeName) {
995                     console.error("Protocol Error: Invalid type of argument '" + key + "' for method '" + agentMethod + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
996                     return;
997                 }
998
999                 request.params[key] = value;
1000                 hasParams = true;
1001             }
1002             if (!hasParams)
1003                 delete request.params;
1004         }
1005
1006         if (args.length === 1 && !callback) {
1007             if (typeof args[0] !== "undefined") {
1008                 console.error("Protocol Error: Optional callback argument for method '" + agentMethod + "' call must be a function but its type is '" + typeof args[0] + "'.");
1009                 return;
1010             }
1011         }
1012
1013         this._wrapCallbackAndSendMessageObject(request, callback);
1014     },
1015
1016     _wrapCallbackAndSendMessageObject: function(messageObject, callback)
1017     {
1018         messageObject.id = this._wrap(callback);
1019
1020         if (this.dumpInspectorTimeStats) {
1021             var wrappedCallback = this._callbacks[messageObject.id];
1022             wrappedCallback.methodName = messageObject.method;
1023             wrappedCallback.sendRequestTime = Date.now();
1024         }
1025
1026         if (this.dumpInspectorProtocolMessages)
1027             console.log("frontend: " + JSON.stringify(messageObject));
1028
1029         ++this._pendingResponsesCount;
1030         this.sendMessageObjectToBackend(messageObject);
1031     },
1032
1033     sendMessageObjectToBackend: function(messageObject)
1034     {
1035         console.timeStamp(messageObject.method);
1036         var message = JSON.stringify(messageObject);
1037         InspectorFrontendHost.sendMessageToBackend(message);
1038     },
1039
1040     _registerDomainDispatcher: function(domain, dispatcher)
1041     {
1042         this._domainDispatchers[domain] = dispatcher;
1043     },
1044
1045     dispatch: function(message)
1046     {
1047         if (this.dumpInspectorProtocolMessages)
1048             console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
1049
1050         var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
1051
1052         if ("id" in messageObject) { // just a response for some request
1053             if (messageObject.error) {
1054                 messageObject.error.__proto__ = {
1055                     getDescription: function()
1056                     {
1057                         switch(this.code) {
1058                             case -32700: return "Parse error";
1059                             case -32600: return "Invalid Request";
1060                             case -32601: return "Method not found";
1061                             case -32602: return "Invalid params";
1062                             case -32603: return "Internal error";;
1063                             case -32000: return "Server error";
1064                         }
1065                     },
1066
1067                     toString: function()
1068                     {
1069                         var description ="Unknown error code";
1070                         return this.getDescription() + "(" + this.code + "): " + this.message + "." + (this.data ? " " + this.data.join(" ") : "");
1071                     },
1072
1073                     getMessage: function()
1074                     {
1075                         return this.message;
1076                     }
1077                 }
1078
1079                 if (messageObject.error.code !== -32000)
1080                     this.reportProtocolError(messageObject);
1081             }
1082
1083             var arguments = [];
1084             if (messageObject.result) {
1085                 for (var key in messageObject.result)
1086                     arguments.push(messageObject.result[key]);
1087             }
1088
1089             var callback = this._callbacks[messageObject.id];
1090             if (callback) {
1091                 var processingStartTime;
1092                 if (this.dumpInspectorTimeStats && callback.methodName)
1093                     processingStartTime = Date.now();
1094
1095                 arguments.unshift(messageObject.error);
1096                 callback.apply(null, arguments);
1097                 --this._pendingResponsesCount;
1098                 delete this._callbacks[messageObject.id];
1099
1100                 if (this.dumpInspectorTimeStats && callback.methodName)
1101                     console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
1102             }
1103
1104             if (this._scripts && !this._pendingResponsesCount)
1105                 this.runAfterPendingDispatches();
1106
1107             return;
1108         } else {
1109             var method = messageObject.method.split(".");
1110             var domainName = method[0];
1111             var functionName = method[1];
1112             if (!(domainName in this._domainDispatchers)) {
1113                 console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
1114                 return;
1115             }
1116             var dispatcher = this._domainDispatchers[domainName];
1117             if (!(functionName in dispatcher)) {
1118                 console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
1119                 return;
1120             }
1121
1122             if (!this._eventArgs[messageObject.method]) {
1123                 console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
1124                 return;
1125             }
1126
1127             var params = [];
1128             if (messageObject.params) {
1129                 var paramNames = this._eventArgs[messageObject.method];
1130                 for (var i = 0; i < paramNames.length; ++i)
1131                     params.push(messageObject.params[paramNames[i]]);
1132             }
1133
1134             var processingStartTime;
1135             if (this.dumpInspectorTimeStats)
1136                 processingStartTime = Date.now();
1137
1138             dispatcher[functionName].apply(dispatcher, params);
1139
1140             if (this.dumpInspectorTimeStats)
1141                 console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
1142         }
1143     },
1144
1145     reportProtocolError: function(messageObject)
1146     {
1147         console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error);
1148     },
1149
1150     runAfterPendingDispatches: function(script)
1151     {
1152         if (!this._scripts)
1153             this._scripts = [];
1154
1155         if (script)
1156             this._scripts.push(script);
1157
1158         if (!this._pendingResponsesCount) {
1159             var scripts = this._scripts;
1160             this._scripts = []
1161             for (var id = 0; id < scripts.length; ++id)
1162                  scripts[id].call(this);
1163         }
1164     }
1165 }
1166
1167 InspectorBackend = new InspectorBackendStub();""")
1168
1169     param_container_access_code = """
1170     RefPtr<InspectorObject> paramsContainer = requestMessageObject->getObject("params");
1171     InspectorObject* paramsContainerPtr = paramsContainer.get();
1172     InspectorArray* protocolErrorsPtr = protocolErrors.get();
1173 """
1174
1175
1176 type_map = TypeMap(json_api)
1177
1178
1179 class Generator:
1180     frontend_class_field_lines = []
1181     frontend_domain_class_lines = []
1182
1183     method_name_enum_list = []
1184     backend_method_declaration_list = []
1185     backend_method_implementation_list = []
1186     backend_method_name_declaration_list = []
1187     method_handler_list = []
1188     frontend_method_list = []
1189     backend_js_initializer_list = []
1190     backend_js_event_list = []
1191     backend_js_domain_dispatcher_list = []
1192
1193     backend_constructor_param_list = []
1194     backend_constructor_init_list = []
1195     backend_field_list = []
1196     backend_forward_list = []
1197     backend_include_list = []
1198     frontend_constructor_init_list = []
1199
1200     @staticmethod
1201     def go():
1202         for json_domain in json_api["domains"]:
1203             domain_name = json_domain["domain"]
1204             domain_name_lower = domain_name.lower()
1205
1206             domain_data = DomainNameFixes.get_fixed_data(domain_name)
1207
1208             if domain_data.is_disabled(defines_map):
1209                 continue
1210
1211             agent_field_name = domain_data.agent_field_name
1212
1213             frontend_method_declaration_lines = []
1214             if "events" in json_domain:
1215                 for json_event in json_domain["events"]:
1216                     Generator.process_event(json_event, domain_name, frontend_method_declaration_lines)
1217
1218                 Generator.frontend_class_field_lines.append("    %s m_%s;\n" % (domain_name, domain_name_lower))
1219                 Generator.frontend_constructor_init_list.append("    , m_%s(inspectorFrontendChannel)\n" % domain_name_lower)
1220                 Generator.frontend_domain_class_lines.append(Templates.frontend_domain_class.substitute(None,
1221                     domainClassName=domain_name,
1222                     domainFieldName=domain_name_lower,
1223                     frontendDomainMethodDeclarations=join(frontend_method_declaration_lines, "")))
1224             if "commands" in json_domain:
1225                 for json_command in json_domain["commands"]:
1226                     Generator.process_command(json_command, domain_name, agent_field_name)
1227
1228             if not domain_data.skip_js_bind:
1229                 Generator.backend_js_domain_dispatcher_list.append("    this.register%sDispatcher = this._registerDomainDispatcher.bind(this, \"%s\");\n" % (domain_name, domain_name))
1230
1231         sorted_json_domains = list(json_api["domains"])
1232         sorted_json_domains.sort(key=lambda o: o["domain"])
1233
1234         for json_domain in sorted_json_domains:
1235             domain_name = json_domain["domain"]
1236
1237             domain_data = DomainNameFixes.get_fixed_data(domain_name)
1238             if domain_data.is_disabled(defines_map):
1239                 continue
1240
1241             if domain_data.hidden:
1242                 continue
1243             agent_type_name = domain_data.agent_type_name
1244             agent_field_name = domain_data.agent_field_name
1245             Generator.backend_constructor_param_list.append(", %s* %s" % (agent_type_name, agent_field_name))
1246             Generator.backend_constructor_init_list.append("        , m_%s(%s)" % (agent_field_name, agent_field_name))
1247             Generator.backend_field_list.append("    %s* m_%s;" % (agent_type_name, agent_field_name))
1248             Generator.backend_forward_list.append("class %s;" % agent_type_name)
1249             Generator.backend_include_list.append("#include \"%s.h\"" % agent_type_name)
1250
1251     @staticmethod
1252     def process_event(json_event, domain_name, frontend_method_declaration_lines):
1253         event_name = json_event["name"]
1254         parameter_list = []
1255         method_line_list = []
1256         backend_js_event_param_list = []
1257         if "parameters" in json_event:
1258             method_line_list.append("    RefPtr<InspectorObject> paramsObject = InspectorObject::create();\n")
1259             for json_parameter in json_event["parameters"]:
1260                 parameter_name = json_parameter["name"]
1261
1262                 raw_type = resolve_param_raw_type(json_parameter, domain_name)
1263
1264                 json_optional = "optional" in json_parameter and json_parameter["optional"]
1265
1266                 optional_mask = raw_type.is_event_param_check_optional()
1267                 c_type = raw_type.get_c_param_type(ParamType.EVENT, json_optional)
1268
1269                 setter_type = raw_type.get_setter_name()
1270
1271                 optional = optional_mask and json_optional
1272
1273                 parameter_list.append("%s %s" % (c_type.get_text(), parameter_name))
1274
1275                 setter_argument = c_type.get_setter_format() % parameter_name
1276
1277                 setter_code = "    paramsObject->set%s(\"%s\", %s);\n" % (setter_type, parameter_name, setter_argument)
1278                 if optional:
1279                     setter_code = ("    if (%s)\n    " % parameter_name) + setter_code
1280                 method_line_list.append(setter_code)
1281
1282                 backend_js_event_param_list.append("\"%s\"" % parameter_name)
1283             method_line_list.append("    %sMessage->setObject(\"params\", paramsObject);\n" % event_name)
1284         frontend_method_declaration_lines.append(
1285             "        void %s(%s);\n" % (event_name, join(parameter_list, ", ")))
1286
1287         Generator.frontend_method_list.append(Templates.frontend_method.substitute(None,
1288             domainName=domain_name, eventName=event_name,
1289             parameters=join(parameter_list, ", "),
1290             code=join(method_line_list, "")))
1291
1292         Generator.backend_js_event_list.append("    this._eventArgs[\"%s.%s\"] = [%s];\n" % (
1293             domain_name, event_name, join(backend_js_event_param_list, ", ")))
1294
1295     @staticmethod
1296     def process_command(json_command, domain_name, agent_field_name):
1297         json_command_name = json_command["name"]
1298         Generator.method_name_enum_list.append("        k%s_%sCmd," % (domain_name, json_command["name"]))
1299         Generator.method_handler_list.append("        &InspectorBackendDispatcher::%s_%s," % (domain_name, json_command_name))
1300         Generator.backend_method_declaration_list.append("    void %s_%s(long callId, InspectorObject* requestMessageObject);" % (domain_name, json_command_name))
1301
1302         method_in_code = ""
1303         method_out_code = ""
1304         agent_call_param_list = []
1305         response_cook_list = []
1306         request_message_param = ""
1307         js_parameters_text = ""
1308         if "parameters" in json_command:
1309             json_params = json_command["parameters"]
1310             method_in_code += Templates.param_container_access_code
1311             request_message_param = " requestMessageObject"
1312             js_param_list = []
1313
1314             for json_parameter in json_params:
1315                 json_param_name = json_parameter["name"]
1316                 param_raw_type = resolve_param_raw_type(json_parameter, domain_name)
1317
1318                 var_type = param_raw_type.get_c_param_type(ParamType.INPUT, None)
1319                 getter_name = param_raw_type.get_getter_name()
1320
1321                 if "optional" in json_parameter and json_parameter["optional"]:
1322                     code = ("    bool %s_valueFound = false;\n"
1323                             "    %s in_%s = get%s(paramsContainerPtr, \"%s\", &%s_valueFound, protocolErrorsPtr);\n" %
1324                            (json_param_name, var_type.get_text(), json_param_name, getter_name, json_param_name, json_param_name))
1325                     param = ", %s_valueFound ? &in_%s : 0" % (json_param_name, json_param_name)
1326                 else:
1327                     code = ("    %s in_%s = get%s(paramsContainerPtr, \"%s\", 0, protocolErrorsPtr);\n" %
1328                             (var_type.get_text(), json_param_name, getter_name, json_param_name))
1329                     param = ", in_%s" % json_param_name
1330
1331                 method_in_code += code
1332                 agent_call_param_list.append(param)
1333
1334                 js_bind_type = param_raw_type.get_js_bind_type()
1335                 js_param_text = "\"%s\": {\"optional\": %s, \"type\": \"%s\"}" % (
1336                     json_param_name,
1337                     ("true" if ("optional" in json_parameter and json_parameter["optional"]) else "false"),
1338                     js_bind_type)
1339
1340                 js_param_list.append(js_param_text)
1341
1342             js_parameters_text = ", \"params\": {" + join(js_param_list, ", ") + "}"
1343
1344         response_cook_text = ""
1345         if "returns" in json_command:
1346             method_out_code += "\n"
1347             for json_return in json_command["returns"]:
1348
1349                 json_return_name = json_return["name"]
1350                 raw_type = resolve_param_raw_type(json_return, domain_name)
1351                 setter_type = raw_type.get_setter_name()
1352                 initializer = raw_type.get_c_initializer()
1353                 var_type = raw_type.get_c_param_type(ParamType.OUTPUT, None)
1354
1355                 code = "    %s out_%s = %s;\n" % (var_type.get_text(), json_return_name, initializer)
1356                 param = ", &out_%s" % json_return_name
1357                 cook = "        result->set%s(\"%s\", out_%s);\n" % (setter_type, json_return_name, json_return_name)
1358                 if var_type.get_text() == "bool" and "optional" in json_return and json_return["optional"]:
1359                     cook = ("        if (out_%s)\n    " % json_return_name) + cook
1360
1361                 method_out_code += code
1362                 agent_call_param_list.append(param)
1363                 response_cook_list.append(cook)
1364             response_cook_text = "    if (!protocolErrors->length() && !error.length()) {\n%s    }\n" % join(response_cook_list, "")
1365
1366         Generator.backend_method_implementation_list.append(Templates.backend_method.substitute(None,
1367             domainName=domain_name, methodName=json_command_name,
1368             agentField="m_" + agent_field_name,
1369             methodInCode=method_in_code,
1370             methodOutCode=method_out_code,
1371             agentCallParams=join(agent_call_param_list, ""),
1372             requestMessageObject=request_message_param,
1373             responseCook=response_cook_text))
1374         Generator.backend_method_name_declaration_list.append("    \"%s.%s\"," % (domain_name, json_command_name))
1375
1376         Generator.backend_js_initializer_list.append("        this._registerDelegate('{\"method\": \"%s.%s\"%s, \"id\": 0}');\n" % (domain_name, json_command_name, js_parameters_text))
1377
1378
1379 Generator.go()
1380
1381 backend_h_file = open(output_header_dirname + "/InspectorBackendDispatcher.h", "w")
1382 backend_cpp_file = open(output_cpp_dirname + "/InspectorBackendDispatcher.cpp", "w")
1383
1384 frontend_h_file = open(output_header_dirname + "/InspectorFrontend.h", "w")
1385 frontend_cpp_file = open(output_cpp_dirname + "/InspectorFrontend.cpp", "w")
1386
1387 backend_js_file = open(output_cpp_dirname + "/InspectorBackendStub.js", "w")
1388
1389
1390 frontend_h_file.write(Templates.frontend_h.substitute(None,
1391          fieldDeclarations=join(Generator.frontend_class_field_lines, ""),
1392          domainClassList=join(Generator.frontend_domain_class_lines, "")))
1393
1394 backend_h_file.write(Templates.backend_h.substitute(None,
1395     constructorInit=join(Generator.backend_constructor_init_list, "\n"),
1396     constructorParams=join(Generator.backend_constructor_param_list, ""),
1397     methodNamesEnumContent=join(Generator.method_name_enum_list, "\n"),
1398     methodDeclarations=join(Generator.backend_method_declaration_list, "\n"),
1399     fieldDeclarations=join(Generator.backend_field_list, "\n"),
1400     forwardDeclarations=join(Generator.backend_forward_list, "\n")))
1401
1402 frontend_cpp_file.write(Templates.frontend_cpp.substitute(None,
1403     constructorInit=join(Generator.frontend_constructor_init_list, ""),
1404     methods=join(Generator.frontend_method_list, "\n")))
1405
1406 backend_cpp_file.write(Templates.backend_cpp.substitute(None,
1407     methodNameDeclarations=join(Generator.backend_method_name_declaration_list, "\n"),
1408     includes=join(Generator.backend_include_list, "\n"),
1409     methods=join(Generator.backend_method_implementation_list, "\n"),
1410     messageHandlers=join(Generator.method_handler_list, "\n")))
1411
1412 backend_js_file.write(Templates.backend_js.substitute(None,
1413     delegates=join(Generator.backend_js_initializer_list, ""),
1414     eventArgs=join(Generator.backend_js_event_list, ""),
1415     domainDispatchers=join(Generator.backend_js_domain_dispatcher_list, "")))
1416
1417 backend_h_file.close()
1418 backend_cpp_file.close()
1419
1420 frontend_h_file.close()
1421 frontend_cpp_file.close()
1422
1423 backend_js_file.close()