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