• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2013 Google Inc. All rights reserved.
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions are
5# met:
6#
7#     * Redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer.
9#     * Redistributions in binary form must reproduce the above
10# copyright notice, this list of conditions and the following disclaimer
11# in the documentation and/or other materials provided with the
12# distribution.
13#     * Neither the name of Google Inc. nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29# THis file contains string resources for CodeGeneratorInspector.
30# Its syntax is a Python syntax subset, suitable for manual parsing.
31
32frontend_domain_class = (
33"""    class $domainClassName {
34    public:
35        $domainClassName(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }
36${frontendDomainMethodDeclarations}
37        void flush() { m_inspectorFrontendChannel->flush(); }
38    private:
39        InspectorFrontendChannel* m_inspectorFrontendChannel;
40    };
41
42    $domainClassName* $domainFieldName() { return &m_$domainFieldName; }
43
44""")
45
46backend_method = (
47"""void InspectorBackendDispatcherImpl::${domainName}_$methodName(long callId, JSONObject*$requestMessageObject, JSONArray* protocolErrors)
48{
49    if (!$agentField)
50        protocolErrors->pushString("${domainName} handler is not available.");
51$methodCode
52    if (protocolErrors->length()) {
53        reportProtocolError(&callId, InvalidParams, String::format(InvalidParamsFormatString, commandName($commandNameIndex)), protocolErrors);
54        return;
55    }
56$agentCallParamsDeclaration
57    $agentField->$methodName($agentCallParams);
58$responseCook
59    sendResponse(callId, $sendResponseCallParams);
60}
61""")
62
63frontend_method = ("""void InspectorFrontend::$domainName::$eventName($parameters)
64{
65    RefPtr<JSONObject> jsonMessage = JSONObject::create();
66    jsonMessage->setString("method", "$domainName.$eventName");
67$code    if (m_inspectorFrontendChannel)
68        m_inspectorFrontendChannel->sendMessageToFrontend(jsonMessage.release());
69}
70""")
71
72callback_main_methods = (
73"""InspectorBackendDispatcher::$agentName::$callbackName::$callbackName(PassRefPtr<InspectorBackendDispatcherImpl> backendImpl, int id) : CallbackBase(backendImpl, id) {}
74
75void InspectorBackendDispatcher::$agentName::$callbackName::sendSuccess($parameters)
76{
77    RefPtr<JSONObject> jsonMessage = JSONObject::create();
78$code    sendIfActive(jsonMessage, ErrorString(), PassRefPtr<JSONValue>());
79}
80""")
81
82callback_failure_method = (
83"""void InspectorBackendDispatcher::$agentName::$callbackName::sendFailure(const ErrorString& error, $parameter)
84{
85    ASSERT(error.length());
86    RefPtr<JSONValue> errorDataValue;
87    if (error) {
88        errorDataValue = $argument;
89    }
90    sendIfActive(nullptr, error, errorDataValue.release());
91}
92""")
93
94
95frontend_h = (
96"""#ifndef InspectorFrontend_h
97#define InspectorFrontend_h
98
99#include "InspectorTypeBuilder.h"
100#include "core/inspector/InspectorFrontendChannel.h"
101#include "platform/JSONValues.h"
102#include "wtf/PassRefPtr.h"
103#include "wtf/text/WTFString.h"
104
105namespace WebCore {
106
107typedef String ErrorString;
108
109class InspectorFrontend {
110public:
111    InspectorFrontend(InspectorFrontendChannel*);
112    InspectorFrontendChannel* channel() { return m_inspectorFrontendChannel; }
113
114$domainClassList
115private:
116    InspectorFrontendChannel* m_inspectorFrontendChannel;
117${fieldDeclarations}};
118
119} // namespace WebCore
120#endif // !defined(InspectorFrontend_h)
121""")
122
123backend_h = (
124"""#ifndef InspectorBackendDispatcher_h
125#define InspectorBackendDispatcher_h
126
127#include "InspectorTypeBuilder.h"
128
129#include "wtf/PassRefPtr.h"
130#include "wtf/RefCounted.h"
131#include "wtf/text/WTFString.h"
132
133namespace WebCore {
134
135class JSONObject;
136class JSONArray;
137class InspectorFrontendChannel;
138
139typedef String ErrorString;
140
141class InspectorBackendDispatcherImpl;
142
143class InspectorBackendDispatcher: public RefCounted<InspectorBackendDispatcher> {
144public:
145    static PassRefPtr<InspectorBackendDispatcher> create(InspectorFrontendChannel* inspectorFrontendChannel);
146    virtual ~InspectorBackendDispatcher() { }
147
148    class CallbackBase: public RefCounted<CallbackBase> {
149    public:
150        CallbackBase(PassRefPtr<InspectorBackendDispatcherImpl> backendImpl, int id);
151        virtual ~CallbackBase();
152        void sendFailure(const ErrorString&);
153        bool isActive();
154
155    protected:
156        void sendIfActive(PassRefPtr<JSONObject> partialMessage, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData);
157
158    private:
159        void disable() { m_alreadySent = true; }
160
161        RefPtr<InspectorBackendDispatcherImpl> m_backendImpl;
162        int m_id;
163        bool m_alreadySent;
164
165        friend class InspectorBackendDispatcherImpl;
166    };
167
168$agentInterfaces
169$virtualSetters
170
171    virtual void clearFrontend() = 0;
172
173    enum CommonErrorCode {
174        ParseError = 0,
175        InvalidRequest,
176        MethodNotFound,
177        InvalidParams,
178        InternalError,
179        ServerError,
180        LastEntry,
181    };
182
183    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage) const;
184    virtual void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<JSONValue> data) const = 0;
185    virtual void dispatch(const String& message) = 0;
186    static bool getCommandName(const String& message, String* result);
187
188    enum MethodNames {
189$methodNamesEnumContent
190
191        kMethodNamesEnumSize
192    };
193
194    static const char* commandName(MethodNames);
195
196private:
197    static const char commandNames[];
198    static const size_t commandNamesIndex[];
199};
200
201} // namespace WebCore
202#endif // !defined(InspectorBackendDispatcher_h)
203
204
205""")
206
207backend_cpp = (
208"""
209
210#include "config.h"
211#include "InspectorBackendDispatcher.h"
212
213#include "core/inspector/InspectorFrontendChannel.h"
214#include "core/inspector/JSONParser.h"
215#include "platform/JSONValues.h"
216#include "wtf/text/CString.h"
217#include "wtf/text/WTFString.h"
218
219namespace WebCore {
220
221const char InspectorBackendDispatcher::commandNames[] = {
222$methodNameDeclarations
223};
224
225const size_t InspectorBackendDispatcher::commandNamesIndex[] = {
226$methodNameDeclarationsIndex
227};
228
229const char* InspectorBackendDispatcher::commandName(MethodNames index) {
230    COMPILE_ASSERT(static_cast<int>(kMethodNamesEnumSize) == WTF_ARRAY_LENGTH(commandNamesIndex), command_name_array_problem);
231    return commandNames + commandNamesIndex[index];
232}
233
234class InspectorBackendDispatcherImpl : public InspectorBackendDispatcher {
235public:
236    InspectorBackendDispatcherImpl(InspectorFrontendChannel* inspectorFrontendChannel)
237        : m_inspectorFrontendChannel(inspectorFrontendChannel)
238$constructorInit
239    { }
240
241    virtual void clearFrontend() { m_inspectorFrontendChannel = 0; }
242    virtual void dispatch(const String& message);
243    virtual void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<JSONValue> data) const;
244    using InspectorBackendDispatcher::reportProtocolError;
245
246    void sendResponse(long callId, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData, PassRefPtr<JSONObject> result);
247    bool isActive() { return m_inspectorFrontendChannel; }
248
249$setters
250private:
251$methodDeclarations
252
253    InspectorFrontendChannel* m_inspectorFrontendChannel;
254$fieldDeclarations
255
256    template<typename R, typename V, typename V0>
257    static R getPropertyValueImpl(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name);
258
259    static int getInt(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
260    static double getDouble(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
261    static String getString(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
262    static bool getBoolean(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
263    static PassRefPtr<JSONObject> getObject(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
264    static PassRefPtr<JSONArray> getArray(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
265
266    void sendResponse(long callId, ErrorString invocationError, PassRefPtr<JSONObject> result)
267    {
268        sendResponse(callId, invocationError, RefPtr<JSONValue>(), result);
269    }
270    void sendResponse(long callId, ErrorString invocationError)
271    {
272        sendResponse(callId, invocationError, RefPtr<JSONValue>(), JSONObject::create());
273    }
274    static const char InvalidParamsFormatString[];
275};
276
277const char InspectorBackendDispatcherImpl::InvalidParamsFormatString[] = "Some arguments of method '%s' can't be processed";
278
279$methods
280
281PassRefPtr<InspectorBackendDispatcher> InspectorBackendDispatcher::create(InspectorFrontendChannel* inspectorFrontendChannel)
282{
283    return adoptRef(new InspectorBackendDispatcherImpl(inspectorFrontendChannel));
284}
285
286
287void InspectorBackendDispatcherImpl::dispatch(const String& message)
288{
289    RefPtr<InspectorBackendDispatcher> protect = this;
290    typedef void (InspectorBackendDispatcherImpl::*CallHandler)(long callId, JSONObject* messageObject, JSONArray* protocolErrors);
291    typedef HashMap<String, CallHandler> DispatchMap;
292    DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, );
293    long callId = 0;
294
295    if (dispatchMap.isEmpty()) {
296        static const CallHandler handlers[] = {
297$messageHandlers
298        };
299        for (size_t i = 0; i < kMethodNamesEnumSize; ++i)
300            dispatchMap.add(commandName(static_cast<MethodNames>(i)), handlers[i]);
301    }
302
303    RefPtr<JSONValue> parsedMessage = parseJSON(message);
304    if (!parsedMessage) {
305        reportProtocolError(0, ParseError, "Message must be in JSON format");
306        return;
307    }
308
309    RefPtr<JSONObject> messageObject = parsedMessage->asObject();
310    if (!messageObject) {
311        reportProtocolError(0, InvalidRequest, "Message must be a JSONified object");
312        return;
313    }
314
315    RefPtr<JSONValue> callIdValue = messageObject->get("id");
316    if (!callIdValue) {
317        reportProtocolError(0, InvalidRequest, "'id' property was not found");
318        return;
319    }
320
321    if (!callIdValue->asNumber(&callId)) {
322        reportProtocolError(0, InvalidRequest, "The type of 'id' property must be number");
323        return;
324    }
325
326    RefPtr<JSONValue> methodValue = messageObject->get("method");
327    if (!methodValue) {
328        reportProtocolError(&callId, InvalidRequest, "'method' property wasn't found");
329        return;
330    }
331
332    String method;
333    if (!methodValue->asString(&method)) {
334        reportProtocolError(&callId, InvalidRequest, "The type of 'method' property must be string");
335        return;
336    }
337
338    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
339    if (it == dispatchMap.end()) {
340        reportProtocolError(&callId, MethodNotFound, "'" + method + "' wasn't found");
341        return;
342    }
343
344    RefPtr<JSONArray> protocolErrors = JSONArray::create();
345    ((*this).*it->value)(callId, messageObject.get(), protocolErrors.get());
346}
347
348void InspectorBackendDispatcherImpl::sendResponse(long callId, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData, PassRefPtr<JSONObject> result)
349{
350    if (invocationError.length()) {
351        reportProtocolError(&callId, ServerError, invocationError, errorData);
352        return;
353    }
354
355    RefPtr<JSONObject> responseMessage = JSONObject::create();
356    responseMessage->setNumber("id", callId);
357    responseMessage->setObject("result", result);
358    if (m_inspectorFrontendChannel)
359        m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage.release());
360}
361
362void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage) const
363{
364    reportProtocolError(callId, code, errorMessage, PassRefPtr<JSONValue>());
365}
366
367void InspectorBackendDispatcherImpl::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage, PassRefPtr<JSONValue> data) const
368{
369    DEFINE_STATIC_LOCAL(Vector<int>,s_commonErrors,);
370    if (!s_commonErrors.size()) {
371        s_commonErrors.insert(ParseError, -32700);
372        s_commonErrors.insert(InvalidRequest, -32600);
373        s_commonErrors.insert(MethodNotFound, -32601);
374        s_commonErrors.insert(InvalidParams, -32602);
375        s_commonErrors.insert(InternalError, -32603);
376        s_commonErrors.insert(ServerError, -32000);
377    }
378    ASSERT(code >=0);
379    ASSERT((unsigned)code < s_commonErrors.size());
380    ASSERT(s_commonErrors[code]);
381    RefPtr<JSONObject> error = JSONObject::create();
382    error->setNumber("code", s_commonErrors[code]);
383    error->setString("message", errorMessage);
384    ASSERT(error);
385    if (data)
386        error->setValue("data", data);
387    RefPtr<JSONObject> message = JSONObject::create();
388    message->setObject("error", error);
389    if (callId)
390        message->setNumber("id", *callId);
391    else
392        message->setValue("id", JSONValue::null());
393    if (m_inspectorFrontendChannel)
394        m_inspectorFrontendChannel->sendMessageToFrontend(message.release());
395}
396
397template<typename R, typename V, typename V0>
398R InspectorBackendDispatcherImpl::getPropertyValueImpl(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name)
399{
400    ASSERT(protocolErrors);
401
402    if (valueFound)
403        *valueFound = false;
404
405    V value = initial_value;
406
407    if (!object) {
408        if (!valueFound) {
409            // Required parameter in missing params container.
410            protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type '%s'.", name, type_name));
411        }
412        return value;
413    }
414
415    JSONObject::const_iterator end = object->end();
416    JSONObject::const_iterator valueIterator = object->find(name);
417
418    if (valueIterator == end) {
419        if (!valueFound)
420            protocolErrors->pushString(String::format("Parameter '%s' with type '%s' was not found.", name, type_name));
421        return value;
422    }
423
424    if (!as_method(valueIterator->value.get(), &value))
425        protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be '%s'.", name, type_name));
426    else
427        if (valueFound)
428            *valueFound = true;
429    return value;
430}
431
432struct AsMethodBridges {
433    static bool asInt(JSONValue* value, int* output) { return value->asNumber(output); }
434    static bool asDouble(JSONValue* value, double* output) { return value->asNumber(output); }
435    static bool asString(JSONValue* value, String* output) { return value->asString(output); }
436    static bool asBoolean(JSONValue* value, bool* output) { return value->asBoolean(output); }
437    static bool asObject(JSONValue* value, RefPtr<JSONObject>* output) { return value->asObject(output); }
438    static bool asArray(JSONValue* value, RefPtr<JSONArray>* output) { return value->asArray(output); }
439};
440
441int InspectorBackendDispatcherImpl::getInt(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
442{
443    return getPropertyValueImpl<int, int, int>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asInt, "Number");
444}
445
446double InspectorBackendDispatcherImpl::getDouble(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
447{
448    return getPropertyValueImpl<double, double, double>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asDouble, "Number");
449}
450
451String InspectorBackendDispatcherImpl::getString(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
452{
453    return getPropertyValueImpl<String, String, String>(object, name, valueFound, protocolErrors, "", AsMethodBridges::asString, "String");
454}
455
456bool InspectorBackendDispatcherImpl::getBoolean(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
457{
458    return getPropertyValueImpl<bool, bool, bool>(object, name, valueFound, protocolErrors, false, AsMethodBridges::asBoolean, "Boolean");
459}
460
461PassRefPtr<JSONObject> InspectorBackendDispatcherImpl::getObject(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
462{
463    return getPropertyValueImpl<PassRefPtr<JSONObject>, RefPtr<JSONObject>, JSONObject*>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asObject, "Object");
464}
465
466PassRefPtr<JSONArray> InspectorBackendDispatcherImpl::getArray(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
467{
468    return getPropertyValueImpl<PassRefPtr<JSONArray>, RefPtr<JSONArray>, JSONArray*>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asArray, "Array");
469}
470
471bool InspectorBackendDispatcher::getCommandName(const String& message, String* result)
472{
473    RefPtr<JSONValue> value = parseJSON(message);
474    if (!value)
475        return false;
476
477    RefPtr<JSONObject> object = value->asObject();
478    if (!object)
479        return false;
480
481    if (!object->getString("method", result))
482        return false;
483
484    return true;
485}
486
487InspectorBackendDispatcher::CallbackBase::CallbackBase(PassRefPtr<InspectorBackendDispatcherImpl> backendImpl, int id)
488    : m_backendImpl(backendImpl), m_id(id), m_alreadySent(false) {}
489
490InspectorBackendDispatcher::CallbackBase::~CallbackBase() {}
491
492void InspectorBackendDispatcher::CallbackBase::sendFailure(const ErrorString& error)
493{
494    ASSERT(error.length());
495    sendIfActive(nullptr, error, PassRefPtr<JSONValue>());
496}
497
498bool InspectorBackendDispatcher::CallbackBase::isActive()
499{
500    return !m_alreadySent && m_backendImpl->isActive();
501}
502
503void InspectorBackendDispatcher::CallbackBase::sendIfActive(PassRefPtr<JSONObject> partialMessage, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData)
504{
505    if (m_alreadySent)
506        return;
507    m_backendImpl->sendResponse(m_id, invocationError, errorData, partialMessage);
508    m_alreadySent = true;
509}
510
511} // namespace WebCore
512
513""")
514
515frontend_cpp = (
516"""
517
518#include "config.h"
519#include "InspectorFrontend.h"
520
521#include "core/inspector/InspectorFrontendChannel.h"
522#include "platform/JSONValues.h"
523#include "wtf/text/CString.h"
524#include "wtf/text/WTFString.h"
525
526namespace WebCore {
527
528InspectorFrontend::InspectorFrontend(InspectorFrontendChannel* inspectorFrontendChannel)
529    : m_inspectorFrontendChannel(inspectorFrontendChannel)
530    , $constructorInit
531{
532}
533
534$methods
535
536} // namespace WebCore
537
538""")
539
540typebuilder_h = (
541"""
542#ifndef InspectorTypeBuilder_h
543#define InspectorTypeBuilder_h
544
545#include "platform/JSONValues.h"
546#include "wtf/Assertions.h"
547#include "wtf/PassRefPtr.h"
548
549namespace WebCore {
550
551namespace TypeBuilder {
552
553template<typename T>
554class OptOutput {
555public:
556    OptOutput() : m_assigned(false) { }
557
558    void operator=(T value)
559    {
560        m_value = value;
561        m_assigned = true;
562    }
563
564    bool isAssigned() { return m_assigned; }
565
566    T getValue()
567    {
568        ASSERT(isAssigned());
569        return m_value;
570    }
571
572private:
573    T m_value;
574    bool m_assigned;
575
576    WTF_MAKE_NONCOPYABLE(OptOutput);
577};
578
579
580// A small transient wrapper around int type, that can be used as a funciton parameter type
581// cleverly disallowing C++ implicit casts from float or double.
582class ExactlyInt {
583public:
584    template<typename T>
585    ExactlyInt(T t) : m_value(cast_to_int<T>(t)) {}
586
587    ExactlyInt() {}
588
589    operator int() { return m_value; }
590private:
591    int m_value;
592
593    template<typename T>
594    static int cast_to_int(T) { return T::default_case_cast_is_not_supported(); }
595};
596
597template<>
598inline int ExactlyInt::cast_to_int<int>(int i) { return i; }
599
600template<>
601inline int ExactlyInt::cast_to_int<unsigned int>(unsigned int i) { return i; }
602
603class RuntimeCastHelper {
604public:
605#if $validatorIfdefName
606    template<JSONValue::Type TYPE>
607    static void assertType(JSONValue* value)
608    {
609        ASSERT(value->type() == TYPE);
610    }
611    static void assertAny(JSONValue*);
612    static void assertInt(JSONValue* value);
613#endif
614};
615
616
617// This class provides "Traits" type for the input type T. It is programmed using C++ template specialization
618// technique. By default it simply takes "ItemTraits" type from T, but it doesn't work with the base types.
619template<typename T>
620struct ArrayItemHelper {
621    typedef typename T::ItemTraits Traits;
622};
623
624template<typename T>
625class Array : public JSONArrayBase {
626private:
627    Array() { }
628
629    JSONArray* openAccessors() {
630        COMPILE_ASSERT(sizeof(JSONArray) == sizeof(Array<T>), cannot_cast);
631        return static_cast<JSONArray*>(static_cast<JSONArrayBase*>(this));
632    }
633
634public:
635    void addItem(PassRefPtr<T> value)
636    {
637        ArrayItemHelper<T>::Traits::pushRefPtr(this->openAccessors(), value);
638    }
639
640    void addItem(T value)
641    {
642        ArrayItemHelper<T>::Traits::pushRaw(this->openAccessors(), value);
643    }
644
645    static PassRefPtr<Array<T> > create()
646    {
647        return adoptRef(new Array<T>());
648    }
649
650    static PassRefPtr<Array<T> > runtimeCast(PassRefPtr<JSONValue> value)
651    {
652        RefPtr<JSONArray> array;
653        bool castRes = value->asArray(&array);
654        ASSERT_UNUSED(castRes, castRes);
655#if $validatorIfdefName
656        assertCorrectValue(array.get());
657#endif  // $validatorIfdefName
658        COMPILE_ASSERT(sizeof(Array<T>) == sizeof(JSONArray), type_cast_problem);
659        return static_cast<Array<T>*>(static_cast<JSONArrayBase*>(array.get()));
660    }
661
662    void concat(PassRefPtr<Array<T> > array)
663    {
664        return ArrayItemHelper<T>::Traits::concat(this->openAccessors(), array->openAccessors());
665    }
666
667#if $validatorIfdefName
668    static void assertCorrectValue(JSONValue* value)
669    {
670        RefPtr<JSONArray> array;
671        bool castRes = value->asArray(&array);
672        ASSERT_UNUSED(castRes, castRes);
673        for (unsigned i = 0; i < array->length(); i++)
674            ArrayItemHelper<T>::Traits::template assertCorrectValue<T>(array->get(i).get());
675    }
676
677#endif // $validatorIfdefName
678};
679
680struct StructItemTraits {
681    static void pushRefPtr(JSONArray* array, PassRefPtr<JSONValue> value)
682    {
683        array->pushValue(value);
684    }
685
686    static void concat(JSONArray* array, JSONArray* anotherArray)
687    {
688        for (JSONArray::iterator it = anotherArray->begin(); it != anotherArray->end(); ++it)
689            array->pushValue(*it);
690    }
691
692#if $validatorIfdefName
693    template<typename T>
694    static void assertCorrectValue(JSONValue* value) {
695        T::assertCorrectValue(value);
696    }
697#endif  // $validatorIfdefName
698};
699
700template<>
701struct ArrayItemHelper<String> {
702    struct Traits {
703        static void pushRaw(JSONArray* array, const String& value)
704        {
705            array->pushString(value);
706        }
707
708#if $validatorIfdefName
709        template<typename T>
710        static void assertCorrectValue(JSONValue* value) {
711            RuntimeCastHelper::assertType<JSONValue::TypeString>(value);
712        }
713#endif  // $validatorIfdefName
714    };
715};
716
717template<>
718struct ArrayItemHelper<int> {
719    struct Traits {
720        static void pushRaw(JSONArray* array, int value)
721        {
722            array->pushInt(value);
723        }
724
725#if $validatorIfdefName
726        template<typename T>
727        static void assertCorrectValue(JSONValue* value) {
728            RuntimeCastHelper::assertInt(value);
729        }
730#endif  // $validatorIfdefName
731    };
732};
733
734template<>
735struct ArrayItemHelper<double> {
736    struct Traits {
737        static void pushRaw(JSONArray* array, double value)
738        {
739            array->pushNumber(value);
740        }
741
742#if $validatorIfdefName
743        template<typename T>
744        static void assertCorrectValue(JSONValue* value) {
745            RuntimeCastHelper::assertType<JSONValue::TypeNumber>(value);
746        }
747#endif  // $validatorIfdefName
748    };
749};
750
751template<>
752struct ArrayItemHelper<bool> {
753    struct Traits {
754        static void pushRaw(JSONArray* array, bool value)
755        {
756            array->pushBoolean(value);
757        }
758
759#if $validatorIfdefName
760        template<typename T>
761        static void assertCorrectValue(JSONValue* value) {
762            RuntimeCastHelper::assertType<JSONValue::TypeBoolean>(value);
763        }
764#endif  // $validatorIfdefName
765    };
766};
767
768template<>
769struct ArrayItemHelper<JSONValue> {
770    struct Traits {
771        static void pushRefPtr(JSONArray* array, PassRefPtr<JSONValue> value)
772        {
773            array->pushValue(value);
774        }
775
776#if $validatorIfdefName
777        template<typename T>
778        static void assertCorrectValue(JSONValue* value) {
779            RuntimeCastHelper::assertAny(value);
780        }
781#endif  // $validatorIfdefName
782    };
783};
784
785template<>
786struct ArrayItemHelper<JSONObject> {
787    struct Traits {
788        static void pushRefPtr(JSONArray* array, PassRefPtr<JSONValue> value)
789        {
790            array->pushValue(value);
791        }
792
793#if $validatorIfdefName
794        template<typename T>
795        static void assertCorrectValue(JSONValue* value) {
796            RuntimeCastHelper::assertType<JSONValue::TypeObject>(value);
797        }
798#endif  // $validatorIfdefName
799    };
800};
801
802template<>
803struct ArrayItemHelper<JSONArray> {
804    struct Traits {
805        static void pushRefPtr(JSONArray* array, PassRefPtr<JSONArray> value)
806        {
807            array->pushArray(value);
808        }
809
810#if $validatorIfdefName
811        template<typename T>
812        static void assertCorrectValue(JSONValue* value) {
813            RuntimeCastHelper::assertType<JSONValue::TypeArray>(value);
814        }
815#endif  // $validatorIfdefName
816    };
817};
818
819template<typename T>
820struct ArrayItemHelper<TypeBuilder::Array<T> > {
821    struct Traits {
822        static void pushRefPtr(JSONArray* array, PassRefPtr<TypeBuilder::Array<T> > value)
823        {
824            array->pushValue(value);
825        }
826
827#if $validatorIfdefName
828        template<typename S>
829        static void assertCorrectValue(JSONValue* value) {
830            S::assertCorrectValue(value);
831        }
832#endif  // $validatorIfdefName
833    };
834};
835
836${forwards}
837
838String getEnumConstantValue(int code);
839
840${typeBuilders}
841} // namespace TypeBuilder
842
843
844} // namespace WebCore
845
846#endif // !defined(InspectorTypeBuilder_h)
847
848""")
849
850typebuilder_cpp = (
851"""
852
853#include "config.h"
854
855#include "InspectorTypeBuilder.h"
856#include "wtf/text/CString.h"
857
858namespace WebCore {
859
860namespace TypeBuilder {
861
862const char* const enum_constant_values[] = {
863$enumConstantValues};
864
865String getEnumConstantValue(int code) {
866    return enum_constant_values[code];
867}
868
869} // namespace TypeBuilder
870
871$implCode
872
873#if $validatorIfdefName
874
875void TypeBuilder::RuntimeCastHelper::assertAny(JSONValue*)
876{
877    // No-op.
878}
879
880
881void TypeBuilder::RuntimeCastHelper::assertInt(JSONValue* value)
882{
883    double v;
884    bool castRes = value->asNumber(&v);
885    ASSERT_UNUSED(castRes, castRes);
886    ASSERT(static_cast<double>(static_cast<int>(v)) == v);
887}
888
889$validatorCode
890
891#endif // $validatorIfdefName
892
893} // namespace WebCore
894
895""")
896
897param_container_access_code = """
898    RefPtr<JSONObject> paramsContainer = requestMessageObject->getObject("params");
899    JSONObject* paramsContainerPtr = paramsContainer.get();
900"""
901
902class_binding_builder_part_1 = (
903"""        AllFieldsSet = %s
904    };
905
906    template<int STATE>
907    class Builder {
908    private:
909        RefPtr<JSONObject> m_result;
910
911        template<int STEP> Builder<STATE | STEP>& castState()
912        {
913            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
914        }
915
916        Builder(PassRefPtr</*%s*/JSONObject> ptr)
917        {
918            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
919            m_result = ptr;
920        }
921        friend class %s;
922    public:
923""")
924
925class_binding_builder_part_2 = ("""
926        Builder<STATE | %s>& set%s(%s value)
927        {
928            COMPILE_ASSERT(!(STATE & %s), property_%s_already_set);
929            m_result->set%s("%s", %s);
930            return castState<%s>();
931        }
932""")
933
934class_binding_builder_part_3 = ("""
935        operator RefPtr<%s>& ()
936        {
937            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
938            COMPILE_ASSERT(sizeof(%s) == sizeof(JSONObject), cannot_cast);
939            return *reinterpret_cast<RefPtr<%s>*>(&m_result);
940        }
941
942        PassRefPtr<%s> release()
943        {
944            return RefPtr<%s>(*this).release();
945        }
946    };
947
948""")
949
950class_binding_builder_part_4 = (
951"""    static Builder<NoFieldsSet> create()
952    {
953        return Builder<NoFieldsSet>(JSONObject::create());
954    }
955""")
956