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