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(PassRefPtrWillBeRawPtr<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 blink { 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 blink 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 "platform/heap/Handle.h" 130#include "wtf/PassRefPtr.h" 131#include "wtf/RefCounted.h" 132#include "wtf/text/WTFString.h" 133 134namespace blink { 135 136class JSONObject; 137class JSONArray; 138class InspectorFrontendChannel; 139 140typedef String ErrorString; 141 142class InspectorBackendDispatcherImpl; 143 144class InspectorBackendDispatcher: public RefCountedWillBeGarbageCollectedFinalized<InspectorBackendDispatcher> { 145public: 146 static PassRefPtrWillBeRawPtr<InspectorBackendDispatcher> create(InspectorFrontendChannel* inspectorFrontendChannel); 147 virtual ~InspectorBackendDispatcher() { } 148 virtual void trace(Visitor*) { } 149 150 class CallbackBase: public RefCountedWillBeGarbageCollectedFinalized<CallbackBase> { 151 public: 152 CallbackBase(PassRefPtrWillBeRawPtr<InspectorBackendDispatcherImpl> backendImpl, int id); 153 virtual ~CallbackBase(); 154 virtual void trace(Visitor*); 155 void sendFailure(const ErrorString&); 156 bool isActive(); 157 158 protected: 159 void sendIfActive(PassRefPtr<JSONObject> partialMessage, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData); 160 161 private: 162 void disable() { m_alreadySent = true; } 163 164 RefPtrWillBeMember<InspectorBackendDispatcherImpl> m_backendImpl; 165 int m_id; 166 bool m_alreadySent; 167 168 friend class InspectorBackendDispatcherImpl; 169 }; 170 171$agentInterfaces 172$virtualSetters 173 174 virtual void clearFrontend() = 0; 175 176 enum CommonErrorCode { 177 ParseError = 0, 178 InvalidRequest, 179 MethodNotFound, 180 InvalidParams, 181 InternalError, 182 ServerError, 183 LastEntry, 184 }; 185 186 void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage) const; 187 virtual void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<JSONValue> data) const = 0; 188 virtual void dispatch(const String& message) = 0; 189 static bool getCommandName(const String& message, String* result); 190 191 enum MethodNames { 192$methodNamesEnumContent 193 194 kMethodNamesEnumSize 195 }; 196 197 static const char* commandName(MethodNames); 198 199private: 200 static const char commandNames[]; 201 static const size_t commandNamesIndex[]; 202}; 203 204} // namespace blink 205#endif // !defined(InspectorBackendDispatcher_h) 206 207 208""") 209 210backend_cpp = ( 211""" 212 213#include "config.h" 214#include "InspectorBackendDispatcher.h" 215 216#include "core/inspector/InspectorFrontendChannel.h" 217#include "core/inspector/JSONParser.h" 218#include "platform/JSONValues.h" 219#include "wtf/text/CString.h" 220#include "wtf/text/WTFString.h" 221 222namespace blink { 223 224const char InspectorBackendDispatcher::commandNames[] = { 225$methodNameDeclarations 226}; 227 228const size_t InspectorBackendDispatcher::commandNamesIndex[] = { 229$methodNameDeclarationsIndex 230}; 231 232const char* InspectorBackendDispatcher::commandName(MethodNames index) { 233 COMPILE_ASSERT(static_cast<int>(kMethodNamesEnumSize) == WTF_ARRAY_LENGTH(commandNamesIndex), command_name_array_problem); 234 return commandNames + commandNamesIndex[index]; 235} 236 237class InspectorBackendDispatcherImpl : public InspectorBackendDispatcher { 238public: 239 InspectorBackendDispatcherImpl(InspectorFrontendChannel* inspectorFrontendChannel) 240 : m_inspectorFrontendChannel(inspectorFrontendChannel) 241$constructorInit 242 { } 243 244 virtual void clearFrontend() { m_inspectorFrontendChannel = 0; } 245 virtual void dispatch(const String& message); 246 virtual void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<JSONValue> data) const; 247 using InspectorBackendDispatcher::reportProtocolError; 248 249 void sendResponse(long callId, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData, PassRefPtr<JSONObject> result); 250 bool isActive() { return m_inspectorFrontendChannel; } 251 252$setters 253private: 254$methodDeclarations 255 256 InspectorFrontendChannel* m_inspectorFrontendChannel; 257$fieldDeclarations 258 259 template<typename R, typename V, typename V0> 260 static R getPropertyValueImpl(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name); 261 262 static int getInt(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors); 263 static double getDouble(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors); 264 static String getString(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors); 265 static bool getBoolean(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors); 266 static PassRefPtr<JSONObject> getObject(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors); 267 static PassRefPtr<JSONArray> getArray(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors); 268 269 void sendResponse(long callId, ErrorString invocationError, PassRefPtr<JSONObject> result) 270 { 271 sendResponse(callId, invocationError, RefPtr<JSONValue>(), result); 272 } 273 void sendResponse(long callId, ErrorString invocationError) 274 { 275 sendResponse(callId, invocationError, RefPtr<JSONValue>(), JSONObject::create()); 276 } 277 static const char InvalidParamsFormatString[]; 278}; 279 280const char InspectorBackendDispatcherImpl::InvalidParamsFormatString[] = "Some arguments of method '%s' can't be processed"; 281 282$methods 283 284PassRefPtrWillBeRawPtr<InspectorBackendDispatcher> InspectorBackendDispatcher::create(InspectorFrontendChannel* inspectorFrontendChannel) 285{ 286 return adoptRefWillBeNoop(new InspectorBackendDispatcherImpl(inspectorFrontendChannel)); 287} 288 289 290void InspectorBackendDispatcherImpl::dispatch(const String& message) 291{ 292 RefPtrWillBeRawPtr<InspectorBackendDispatcher> protect(this); 293 typedef void (InspectorBackendDispatcherImpl::*CallHandler)(long callId, JSONObject* messageObject, JSONArray* protocolErrors); 294 typedef HashMap<String, CallHandler> DispatchMap; 295 DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ); 296 long callId = 0; 297 298 if (dispatchMap.isEmpty()) { 299 static const CallHandler handlers[] = { 300$messageHandlers 301 }; 302 for (size_t i = 0; i < kMethodNamesEnumSize; ++i) 303 dispatchMap.add(commandName(static_cast<MethodNames>(i)), handlers[i]); 304 } 305 306 RefPtr<JSONValue> parsedMessage = parseJSON(message); 307 if (!parsedMessage) { 308 reportProtocolError(0, ParseError, "Message must be in JSON format"); 309 return; 310 } 311 312 RefPtr<JSONObject> messageObject = parsedMessage->asObject(); 313 if (!messageObject) { 314 reportProtocolError(0, InvalidRequest, "Message must be a JSONified object"); 315 return; 316 } 317 318 RefPtr<JSONValue> callIdValue = messageObject->get("id"); 319 if (!callIdValue) { 320 reportProtocolError(0, InvalidRequest, "'id' property was not found"); 321 return; 322 } 323 324 if (!callIdValue->asNumber(&callId)) { 325 reportProtocolError(0, InvalidRequest, "The type of 'id' property must be number"); 326 return; 327 } 328 329 RefPtr<JSONValue> methodValue = messageObject->get("method"); 330 if (!methodValue) { 331 reportProtocolError(&callId, InvalidRequest, "'method' property wasn't found"); 332 return; 333 } 334 335 String method; 336 if (!methodValue->asString(&method)) { 337 reportProtocolError(&callId, InvalidRequest, "The type of 'method' property must be string"); 338 return; 339 } 340 341 HashMap<String, CallHandler>::iterator it = dispatchMap.find(method); 342 if (it == dispatchMap.end()) { 343 reportProtocolError(&callId, MethodNotFound, "'" + method + "' wasn't found"); 344 return; 345 } 346 347 RefPtr<JSONArray> protocolErrors = JSONArray::create(); 348 ((*this).*it->value)(callId, messageObject.get(), protocolErrors.get()); 349} 350 351void InspectorBackendDispatcherImpl::sendResponse(long callId, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData, PassRefPtr<JSONObject> result) 352{ 353 if (invocationError.length()) { 354 reportProtocolError(&callId, ServerError, invocationError, errorData); 355 return; 356 } 357 358 RefPtr<JSONObject> responseMessage = JSONObject::create(); 359 responseMessage->setNumber("id", callId); 360 responseMessage->setObject("result", result); 361 if (m_inspectorFrontendChannel) 362 m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage.release()); 363} 364 365void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage) const 366{ 367 reportProtocolError(callId, code, errorMessage, PassRefPtr<JSONValue>()); 368} 369 370void InspectorBackendDispatcherImpl::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage, PassRefPtr<JSONValue> data) const 371{ 372 DEFINE_STATIC_LOCAL(Vector<int>,s_commonErrors,); 373 if (!s_commonErrors.size()) { 374 s_commonErrors.insert(ParseError, -32700); 375 s_commonErrors.insert(InvalidRequest, -32600); 376 s_commonErrors.insert(MethodNotFound, -32601); 377 s_commonErrors.insert(InvalidParams, -32602); 378 s_commonErrors.insert(InternalError, -32603); 379 s_commonErrors.insert(ServerError, -32000); 380 } 381 ASSERT(code >=0); 382 ASSERT((unsigned)code < s_commonErrors.size()); 383 ASSERT(s_commonErrors[code]); 384 RefPtr<JSONObject> error = JSONObject::create(); 385 error->setNumber("code", s_commonErrors[code]); 386 error->setString("message", errorMessage); 387 ASSERT(error); 388 if (data) 389 error->setValue("data", data); 390 RefPtr<JSONObject> message = JSONObject::create(); 391 message->setObject("error", error); 392 if (callId) 393 message->setNumber("id", *callId); 394 else 395 message->setValue("id", JSONValue::null()); 396 if (m_inspectorFrontendChannel) 397 m_inspectorFrontendChannel->sendMessageToFrontend(message.release()); 398} 399 400template<typename R, typename V, typename V0> 401R InspectorBackendDispatcherImpl::getPropertyValueImpl(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name) 402{ 403 ASSERT(protocolErrors); 404 405 if (valueFound) 406 *valueFound = false; 407 408 V value = initial_value; 409 410 if (!object) { 411 if (!valueFound) { 412 // Required parameter in missing params container. 413 protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type '%s'.", name, type_name)); 414 } 415 return value; 416 } 417 418 JSONObject::const_iterator end = object->end(); 419 JSONObject::const_iterator valueIterator = object->find(name); 420 421 if (valueIterator == end) { 422 if (!valueFound) 423 protocolErrors->pushString(String::format("Parameter '%s' with type '%s' was not found.", name, type_name)); 424 return value; 425 } 426 427 if (!as_method(valueIterator->value.get(), &value)) 428 protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be '%s'.", name, type_name)); 429 else 430 if (valueFound) 431 *valueFound = true; 432 return value; 433} 434 435struct AsMethodBridges { 436 static bool asInt(JSONValue* value, int* output) { return value->asNumber(output); } 437 static bool asDouble(JSONValue* value, double* output) { return value->asNumber(output); } 438 static bool asString(JSONValue* value, String* output) { return value->asString(output); } 439 static bool asBoolean(JSONValue* value, bool* output) { return value->asBoolean(output); } 440 static bool asObject(JSONValue* value, RefPtr<JSONObject>* output) { return value->asObject(output); } 441 static bool asArray(JSONValue* value, RefPtr<JSONArray>* output) { return value->asArray(output); } 442}; 443 444int InspectorBackendDispatcherImpl::getInt(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors) 445{ 446 return getPropertyValueImpl<int, int, int>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asInt, "Number"); 447} 448 449double InspectorBackendDispatcherImpl::getDouble(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors) 450{ 451 return getPropertyValueImpl<double, double, double>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asDouble, "Number"); 452} 453 454String InspectorBackendDispatcherImpl::getString(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors) 455{ 456 return getPropertyValueImpl<String, String, String>(object, name, valueFound, protocolErrors, "", AsMethodBridges::asString, "String"); 457} 458 459bool InspectorBackendDispatcherImpl::getBoolean(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors) 460{ 461 return getPropertyValueImpl<bool, bool, bool>(object, name, valueFound, protocolErrors, false, AsMethodBridges::asBoolean, "Boolean"); 462} 463 464PassRefPtr<JSONObject> InspectorBackendDispatcherImpl::getObject(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors) 465{ 466 return getPropertyValueImpl<PassRefPtr<JSONObject>, RefPtr<JSONObject>, JSONObject*>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asObject, "Object"); 467} 468 469PassRefPtr<JSONArray> InspectorBackendDispatcherImpl::getArray(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors) 470{ 471 return getPropertyValueImpl<PassRefPtr<JSONArray>, RefPtr<JSONArray>, JSONArray*>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asArray, "Array"); 472} 473 474bool InspectorBackendDispatcher::getCommandName(const String& message, String* result) 475{ 476 RefPtr<JSONValue> value = parseJSON(message); 477 if (!value) 478 return false; 479 480 RefPtr<JSONObject> object = value->asObject(); 481 if (!object) 482 return false; 483 484 if (!object->getString("method", result)) 485 return false; 486 487 return true; 488} 489 490InspectorBackendDispatcher::CallbackBase::CallbackBase(PassRefPtrWillBeRawPtr<InspectorBackendDispatcherImpl> backendImpl, int id) 491 : m_backendImpl(backendImpl), m_id(id), m_alreadySent(false) {} 492 493InspectorBackendDispatcher::CallbackBase::~CallbackBase() {} 494 495void InspectorBackendDispatcher::CallbackBase::trace(Visitor* visitor) 496{ 497 visitor->trace(m_backendImpl); 498} 499 500void InspectorBackendDispatcher::CallbackBase::sendFailure(const ErrorString& error) 501{ 502 ASSERT(error.length()); 503 sendIfActive(nullptr, error, PassRefPtr<JSONValue>()); 504} 505 506bool InspectorBackendDispatcher::CallbackBase::isActive() 507{ 508 return !m_alreadySent && m_backendImpl->isActive(); 509} 510 511void InspectorBackendDispatcher::CallbackBase::sendIfActive(PassRefPtr<JSONObject> partialMessage, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData) 512{ 513 if (m_alreadySent) 514 return; 515 m_backendImpl->sendResponse(m_id, invocationError, errorData, partialMessage); 516 m_alreadySent = true; 517} 518 519} // namespace blink 520 521""") 522 523frontend_cpp = ( 524""" 525 526#include "config.h" 527#include "InspectorFrontend.h" 528 529#include "core/inspector/InspectorFrontendChannel.h" 530#include "platform/JSONValues.h" 531#include "wtf/text/CString.h" 532#include "wtf/text/WTFString.h" 533 534namespace blink { 535 536InspectorFrontend::InspectorFrontend(InspectorFrontendChannel* inspectorFrontendChannel) 537 : m_inspectorFrontendChannel(inspectorFrontendChannel) 538 , $constructorInit 539{ 540} 541 542$methods 543 544} // namespace blink 545 546""") 547 548typebuilder_h = ( 549""" 550#ifndef InspectorTypeBuilder_h 551#define InspectorTypeBuilder_h 552 553#include "platform/JSONValues.h" 554#include "wtf/Assertions.h" 555#include "wtf/PassRefPtr.h" 556 557namespace blink { 558 559namespace TypeBuilder { 560 561template<typename T> 562class OptOutput { 563public: 564 OptOutput() : m_assigned(false) { } 565 566 void operator=(T value) 567 { 568 m_value = value; 569 m_assigned = true; 570 } 571 572 bool isAssigned() { return m_assigned; } 573 574 T getValue() 575 { 576 ASSERT(isAssigned()); 577 return m_value; 578 } 579 580private: 581 T m_value; 582 bool m_assigned; 583 584 WTF_MAKE_NONCOPYABLE(OptOutput); 585}; 586 587class RuntimeCastHelper { 588public: 589#if $validatorIfdefName 590 template<JSONValue::Type TYPE> 591 static void assertType(JSONValue* value) 592 { 593 ASSERT(value->type() == TYPE); 594 } 595 static void assertAny(JSONValue*); 596 static void assertInt(JSONValue* value); 597#endif 598}; 599 600 601// This class provides "Traits" type for the input type T. It is programmed using C++ template specialization 602// technique. By default it simply takes "ItemTraits" type from T, but it doesn't work with the base types. 603template<typename T> 604struct ArrayItemHelper { 605 typedef typename T::ItemTraits Traits; 606}; 607 608template<typename T> 609class Array : public JSONArrayBase { 610private: 611 Array() { } 612 613 JSONArray* openAccessors() { 614 COMPILE_ASSERT(sizeof(JSONArray) == sizeof(Array<T>), cannot_cast); 615 return static_cast<JSONArray*>(static_cast<JSONArrayBase*>(this)); 616 } 617 618public: 619 void addItem(PassRefPtr<T> value) 620 { 621 ArrayItemHelper<T>::Traits::pushRefPtr(this->openAccessors(), value); 622 } 623 624 void addItem(T value) 625 { 626 ArrayItemHelper<T>::Traits::pushRaw(this->openAccessors(), value); 627 } 628 629 static PassRefPtr<Array<T> > create() 630 { 631 return adoptRef(new Array<T>()); 632 } 633 634 static PassRefPtr<Array<T> > runtimeCast(PassRefPtr<JSONValue> value) 635 { 636 RefPtr<JSONArray> array; 637 bool castRes = value->asArray(&array); 638 ASSERT_UNUSED(castRes, castRes); 639#if $validatorIfdefName 640 assertCorrectValue(array.get()); 641#endif // $validatorIfdefName 642 COMPILE_ASSERT(sizeof(Array<T>) == sizeof(JSONArray), type_cast_problem); 643 return static_cast<Array<T>*>(static_cast<JSONArrayBase*>(array.get())); 644 } 645 646 void concat(PassRefPtr<Array<T> > array) 647 { 648 return ArrayItemHelper<T>::Traits::concat(this->openAccessors(), array->openAccessors()); 649 } 650 651#if $validatorIfdefName 652 static void assertCorrectValue(JSONValue* value) 653 { 654 RefPtr<JSONArray> array; 655 bool castRes = value->asArray(&array); 656 ASSERT_UNUSED(castRes, castRes); 657 for (unsigned i = 0; i < array->length(); i++) 658 ArrayItemHelper<T>::Traits::template assertCorrectValue<T>(array->get(i).get()); 659 } 660 661#endif // $validatorIfdefName 662}; 663 664struct StructItemTraits { 665 static void pushRefPtr(JSONArray* array, PassRefPtr<JSONValue> value) 666 { 667 array->pushValue(value); 668 } 669 670 static void concat(JSONArray* array, JSONArray* anotherArray) 671 { 672 for (JSONArray::iterator it = anotherArray->begin(); it != anotherArray->end(); ++it) 673 array->pushValue(*it); 674 } 675 676#if $validatorIfdefName 677 template<typename T> 678 static void assertCorrectValue(JSONValue* value) { 679 T::assertCorrectValue(value); 680 } 681#endif // $validatorIfdefName 682}; 683 684template<> 685struct ArrayItemHelper<String> { 686 struct Traits { 687 static void pushRaw(JSONArray* array, const String& value) 688 { 689 array->pushString(value); 690 } 691 692#if $validatorIfdefName 693 template<typename T> 694 static void assertCorrectValue(JSONValue* value) { 695 RuntimeCastHelper::assertType<JSONValue::TypeString>(value); 696 } 697#endif // $validatorIfdefName 698 }; 699}; 700 701template<> 702struct ArrayItemHelper<int> { 703 struct Traits { 704 static void pushRaw(JSONArray* array, int value) 705 { 706 array->pushInt(value); 707 } 708 709#if $validatorIfdefName 710 template<typename T> 711 static void assertCorrectValue(JSONValue* value) { 712 RuntimeCastHelper::assertInt(value); 713 } 714#endif // $validatorIfdefName 715 }; 716}; 717 718template<> 719struct ArrayItemHelper<double> { 720 struct Traits { 721 static void pushRaw(JSONArray* array, double value) 722 { 723 array->pushNumber(value); 724 } 725 726#if $validatorIfdefName 727 template<typename T> 728 static void assertCorrectValue(JSONValue* value) { 729 RuntimeCastHelper::assertType<JSONValue::TypeNumber>(value); 730 } 731#endif // $validatorIfdefName 732 }; 733}; 734 735template<> 736struct ArrayItemHelper<bool> { 737 struct Traits { 738 static void pushRaw(JSONArray* array, bool value) 739 { 740 array->pushBoolean(value); 741 } 742 743#if $validatorIfdefName 744 template<typename T> 745 static void assertCorrectValue(JSONValue* value) { 746 RuntimeCastHelper::assertType<JSONValue::TypeBoolean>(value); 747 } 748#endif // $validatorIfdefName 749 }; 750}; 751 752template<> 753struct ArrayItemHelper<JSONValue> { 754 struct Traits { 755 static void pushRefPtr(JSONArray* array, PassRefPtr<JSONValue> value) 756 { 757 array->pushValue(value); 758 } 759 760#if $validatorIfdefName 761 template<typename T> 762 static void assertCorrectValue(JSONValue* value) { 763 RuntimeCastHelper::assertAny(value); 764 } 765#endif // $validatorIfdefName 766 }; 767}; 768 769template<> 770struct ArrayItemHelper<JSONObject> { 771 struct Traits { 772 static void pushRefPtr(JSONArray* array, PassRefPtr<JSONValue> value) 773 { 774 array->pushValue(value); 775 } 776 777#if $validatorIfdefName 778 template<typename T> 779 static void assertCorrectValue(JSONValue* value) { 780 RuntimeCastHelper::assertType<JSONValue::TypeObject>(value); 781 } 782#endif // $validatorIfdefName 783 }; 784}; 785 786template<> 787struct ArrayItemHelper<JSONArray> { 788 struct Traits { 789 static void pushRefPtr(JSONArray* array, PassRefPtr<JSONArray> value) 790 { 791 array->pushArray(value); 792 } 793 794#if $validatorIfdefName 795 template<typename T> 796 static void assertCorrectValue(JSONValue* value) { 797 RuntimeCastHelper::assertType<JSONValue::TypeArray>(value); 798 } 799#endif // $validatorIfdefName 800 }; 801}; 802 803template<typename T> 804struct ArrayItemHelper<TypeBuilder::Array<T> > { 805 struct Traits { 806 static void pushRefPtr(JSONArray* array, PassRefPtr<TypeBuilder::Array<T> > value) 807 { 808 array->pushValue(value); 809 } 810 811#if $validatorIfdefName 812 template<typename S> 813 static void assertCorrectValue(JSONValue* value) { 814 S::assertCorrectValue(value); 815 } 816#endif // $validatorIfdefName 817 }; 818}; 819 820${forwards} 821 822String getEnumConstantValue(int code); 823 824${typeBuilders} 825} // namespace TypeBuilder 826 827 828} // namespace blink 829 830#endif // !defined(InspectorTypeBuilder_h) 831 832""") 833 834typebuilder_cpp = ( 835""" 836 837#include "config.h" 838 839#include "InspectorTypeBuilder.h" 840#include "wtf/text/CString.h" 841 842namespace blink { 843 844namespace TypeBuilder { 845 846const char* const enum_constant_values[] = { 847$enumConstantValues}; 848 849String getEnumConstantValue(int code) { 850 return enum_constant_values[code]; 851} 852 853} // namespace TypeBuilder 854 855$implCode 856 857#if $validatorIfdefName 858 859void TypeBuilder::RuntimeCastHelper::assertAny(JSONValue*) 860{ 861 // No-op. 862} 863 864 865void TypeBuilder::RuntimeCastHelper::assertInt(JSONValue* value) 866{ 867 double v; 868 bool castRes = value->asNumber(&v); 869 ASSERT_UNUSED(castRes, castRes); 870 ASSERT(static_cast<double>(static_cast<int>(v)) == v); 871} 872 873$validatorCode 874 875#endif // $validatorIfdefName 876 877} // namespace blink 878 879""") 880 881param_container_access_code = """ 882 RefPtr<JSONObject> paramsContainer = requestMessageObject->getObject("params"); 883 JSONObject* paramsContainerPtr = paramsContainer.get(); 884""" 885 886class_binding_builder_part_1 = ( 887""" AllFieldsSet = %s 888 }; 889 890 template<int STATE> 891 class Builder { 892 private: 893 RefPtr<JSONObject> m_result; 894 895 template<int STEP> Builder<STATE | STEP>& castState() 896 { 897 return *reinterpret_cast<Builder<STATE | STEP>*>(this); 898 } 899 900 Builder(PassRefPtr</*%s*/JSONObject> ptr) 901 { 902 COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state); 903 m_result = ptr; 904 } 905 friend class %s; 906 public: 907""") 908 909class_binding_builder_part_2 = (""" 910 Builder<STATE | %s>& set%s(%s value) 911 { 912 COMPILE_ASSERT(!(STATE & %s), property_%s_already_set); 913 m_result->set%s("%s", %s); 914 return castState<%s>(); 915 } 916""") 917 918class_binding_builder_part_3 = (""" 919 operator RefPtr<%s>& () 920 { 921 COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready); 922 COMPILE_ASSERT(sizeof(%s) == sizeof(JSONObject), cannot_cast); 923 return *reinterpret_cast<RefPtr<%s>*>(&m_result); 924 } 925 926 PassRefPtr<%s> release() 927 { 928 return RefPtr<%s>(*this).release(); 929 } 930 }; 931 932""") 933 934class_binding_builder_part_4 = ( 935""" static Builder<NoFieldsSet> create() 936 { 937 return Builder<NoFieldsSet>(JSONObject::create()); 938 } 939""") 940