DevTools: generate string16-based handlers for v8_inspector.

BUG=580337

Review URL: https://codereview.chromium.org/1767883002

Cr-Original-Commit-Position: refs/heads/master@{#379933}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 06595f0c4376466cfdd21d2c7f6fc91d9c1142a6
diff --git a/Array.h b/Array.h
index 4ab8466..087f848 100644
--- a/Array.h
+++ b/Array.h
@@ -8,9 +8,9 @@
 #include "platform/PlatformExport.h"
 #include "platform/inspector_protocol/Collections.h"
 #include "platform/inspector_protocol/ErrorSupport.h"
+#include "platform/inspector_protocol/String16.h"
 #include "platform/inspector_protocol/ValueConversions.h"
 #include "platform/inspector_protocol/Values.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 namespace protocol {
@@ -33,7 +33,7 @@
         errors->push();
         OwnPtr<Array<T>> result = adoptPtr(new Array<T>());
         for (size_t i = 0; i < array->size(); ++i) {
-            errors->setName("[" + String::number(i) + "]");
+            errors->setName("[" + String16::number(i) + "]");
             T item = FromValue<T>::parse(array->at(i), errors);
             result->m_vector.append(item);
         }
@@ -71,6 +71,7 @@
 };
 
 template<> class Array<String> : public ArrayBase<String> {};
+template<> class Array<String16> : public ArrayBase<String16> {};
 template<> class Array<int> : public ArrayBase<int> {};
 template<> class Array<double> : public ArrayBase<double> {};
 template<> class Array<bool> : public ArrayBase<bool> {};
@@ -93,7 +94,7 @@
         OwnPtr<Array<T>> result = adoptPtr(new Array<T>());
         errors->push();
         for (size_t i = 0; i < array->size(); ++i) {
-            errors->setName("[" + String::number(i) + "]");
+            errors->setName("[" + String16::number(i) + "]");
             OwnPtr<T> item = FromValue<T>::parse(array->at(i), errors);
             result->m_vector.append(item.release());
         }
diff --git a/CodeGenerator.py b/CodeGenerator.py
index 43c9c56..9297b7e 100644
--- a/CodeGenerator.py
+++ b/CodeGenerator.py
@@ -90,6 +90,8 @@
         if not isinstance(json, dict):
             return
         for key in json:
+            if key == "type" and json[key] == "string":
+                json[key] = domain_name + ".string"
             if key != "$ref":
                 patch_full_qualified_refs_in_domain(json[key], domain_name)
                 continue
@@ -139,19 +141,31 @@
     }
 
 
-def create_primitive_type_definition(type):
-    if type == "string":
+def create_string_type_definition(domain):
+    if domain in ["Runtime", "Debugger", "Profiler", "HeapProfiler"]:
         return {
-            "return_type": "String",
-            "pass_type": "const String&",
+            "return_type": "String16",
+            "pass_type": "const String16&",
             "to_pass_type": "%s",
             "to_raw_type": "%s",
-            "type": "String",
-            "raw_type": "String",
-            "raw_pass_type": "const String&",
-            "raw_return_type": "String",
+            "type": "String16",
+            "raw_type": "String16",
+            "raw_pass_type": "const String16&",
+            "raw_return_type": "String16",
         }
+    return {
+        "return_type": "String",
+        "pass_type": "const String&",
+        "to_pass_type": "%s",
+        "to_raw_type": "%s",
+        "type": "String",
+        "raw_type": "String",
+        "raw_pass_type": "const String&",
+        "raw_return_type": "String",
+    }
 
+
+def create_primitive_type_definition(type):
     typedefs = {
         "number": "double",
         "integer": "int",
@@ -174,14 +188,12 @@
     }
 
 type_definitions = {}
-type_definitions["string"] = create_primitive_type_definition("string")
 type_definitions["number"] = create_primitive_type_definition("number")
 type_definitions["integer"] = create_primitive_type_definition("integer")
 type_definitions["boolean"] = create_primitive_type_definition("boolean")
 type_definitions["object"] = create_object_type_definition()
 type_definitions["any"] = create_any_type_definition()
 
-
 def wrap_array_definition(type):
     return {
         "return_type": "PassOwnPtr<protocol::Array<%s>>" % type["raw_type"],
@@ -199,6 +211,7 @@
 
 def create_type_definitions():
     for domain in json_api["domains"]:
+        type_definitions[domain["domain"] + ".string"] = create_string_type_definition(domain["domain"])
         if not ("types" in domain):
             continue
         for type in domain["types"]:
@@ -207,6 +220,8 @@
             elif type["type"] == "array":
                 items_type = type["items"]["type"]
                 type_definitions[domain["domain"] + "." + type["id"]] = wrap_array_definition(type_definitions[items_type])
+            elif type["type"] == domain["domain"] + ".string":
+                type_definitions[domain["domain"] + "." + type["id"]] = create_string_type_definition(domain["domain"])
             else:
                 type_definitions[domain["domain"] + "." + type["id"]] = create_primitive_type_definition(type["type"])
 
diff --git a/Collections.h b/Collections.h
index 0e3e351..f651e45 100644
--- a/Collections.h
+++ b/Collections.h
@@ -5,6 +5,6 @@
 #ifndef Collections_h
 #define Collections_h
 
-#include "CollectionsWTF.h"
+#include "platform/inspector_protocol/CollectionsWTF.h"
 
 #endif // !defined(Collections_h)
diff --git a/CollectionsSTL.h b/CollectionsSTL.h
index 4d4ea56..d141f30 100644
--- a/CollectionsSTL.h
+++ b/CollectionsSTL.h
@@ -8,7 +8,6 @@
 #include "wtf/Allocator.h"
 #include "wtf/HashMap.h"
 #include "wtf/PassOwnPtr.h"
-#include "wtf/text/StringHash.h"
 
 #include <algorithm>
 #include <unordered_map>
diff --git a/Dispatcher_cpp.template b/Dispatcher_cpp.template
index f475712..3cb3584 100644
--- a/Dispatcher_cpp.template
+++ b/Dispatcher_cpp.template
@@ -70,8 +70,8 @@
         return weak.release();
     }
 
-    virtual void dispatch(int sessionId, const String& message);
-    virtual void reportProtocolError(int sessionId, int callId, CommonErrorCode, const String& errorMessage, ErrorSupport* errors) const;
+    virtual void dispatch(int sessionId, const String16& message);
+    virtual void reportProtocolError(int sessionId, int callId, CommonErrorCode, const String16& errorMessage, ErrorSupport* errors) const;
     using Dispatcher::reportProtocolError;
 
     void sendResponse(int sessionId, int callId, const ErrorString& invocationError, ErrorSupport* errors, PassOwnPtr<protocol::DictionaryValue> result);
@@ -84,7 +84,7 @@
     friend class CallbackBase;
     friend class DispatcherImplWeakPtr;
     using CallHandler = void (DispatcherImpl::*)(int sessionId, int callId, PassOwnPtr<DictionaryValue> messageObject, ErrorSupport* errors);
-    using DispatchMap = protocol::HashMap<String, CallHandler>;
+    using DispatchMap = protocol::HashMap<String16, CallHandler>;
 
 {% for domain in api.domains %}
   {% for command in domain.commands %}
@@ -110,7 +110,7 @@
         sendResponse(sessionId, callId, invocationError, nullptr, DictionaryValue::create());
     }
 
-    static const char InvalidParamsFormatString[];
+    static const char kInvalidRequest[];
 
     DispatchMap m_dispatchMap;
     protocol::Vector<int> m_commonErrors;
@@ -123,7 +123,8 @@
         m_dispatcher->m_weakPtrs.remove(this);
 }
 
-const char DispatcherImpl::InvalidParamsFormatString[] = "Some arguments of method '%s' can't be processed";
+const char DispatcherImpl::kInvalidRequest[] = "Invalid request";
+
 {% for domain in api.domains %}
   {% for command in domain.commands %}
     {% if "redirect" in command %}{% continue %}{% endif %}
@@ -161,7 +162,7 @@
         errors->addError("{{domain.domain}} handler is not available.");
 
     if (errors->hasErrors()) {
-        reportProtocolError(sessionId, callId, InvalidParams, String::format(InvalidParamsFormatString, "{{domain.domain}}.{{command.name}}"), errors);
+        reportProtocolError(sessionId, callId, InvalidParams, kInvalidRequest, errors);
         return;
     }
     {% if "parameters" in command %}
@@ -184,7 +185,7 @@
       {% endfor %}
     errors->pop();
     if (errors->hasErrors()) {
-        reportProtocolError(sessionId, callId, InvalidParams, String::format(InvalidParamsFormatString, "{{domain.domain}}.{{command.name}}"), errors);
+        reportProtocolError(sessionId, callId, InvalidParams, kInvalidRequest, errors);
         return;
     }
     {% endif %}
@@ -246,7 +247,7 @@
     return adoptPtr(new DispatcherImpl(frontendChannel));
 }
 
-void DispatcherImpl::dispatch(int sessionId, const String& message)
+void DispatcherImpl::dispatch(int sessionId, const String16& message)
 {
     int callId = 0;
     OwnPtr<protocol::Value> parsedMessage = parseJSON(message);
@@ -259,11 +260,11 @@
     ASSERT_UNUSED(success, success);
 
     protocol::Value* methodValue = messageObject->get("method");
-    String method;
+    String16 method;
     success = methodValue && methodValue->asString(&method);
     ASSERT_UNUSED(success, success);
 
-    protocol::HashMap<String, CallHandler>::iterator it = m_dispatchMap.find(method);
+    protocol::HashMap<String16, CallHandler>::iterator it = m_dispatchMap.find(method);
     if (it == m_dispatchMap.end()) {
         reportProtocolError(sessionId, callId, MethodNotFound, "'" + method + "' wasn't found");
         return;
@@ -287,13 +288,13 @@
         m_frontendChannel->sendProtocolResponse(sessionId, callId, responseMessage.release());
 }
 
-void Dispatcher::reportProtocolError(int sessionId, int callId, CommonErrorCode code, const String& errorMessage) const
+void Dispatcher::reportProtocolError(int sessionId, int callId, CommonErrorCode code, const String16& errorMessage) const
 {
     ErrorSupport errors;
     reportProtocolError(sessionId, callId, code, errorMessage, &errors);
 }
 
-void DispatcherImpl::reportProtocolError(int sessionId, int callId, CommonErrorCode code, const String& errorMessage, ErrorSupport* errors) const
+void DispatcherImpl::reportProtocolError(int sessionId, int callId, CommonErrorCode code, const String16& errorMessage, ErrorSupport* errors) const
 {
     ASSERT(code >=0);
     ASSERT((unsigned)code < m_commonErrors.size());
@@ -311,7 +312,7 @@
         m_frontendChannel->sendProtocolResponse(sessionId, callId, message.release());
 }
 
-bool Dispatcher::getCommandName(const String& message, String* result)
+bool Dispatcher::getCommandName(const String16& message, String16* result)
 {
     OwnPtr<protocol::Value> value = parseJSON(message);
     if (!value)
diff --git a/Dispatcher_h.template b/Dispatcher_h.template
index 3a9f3f0..2cde7f1 100644
--- a/Dispatcher_h.template
+++ b/Dispatcher_h.template
@@ -14,7 +14,6 @@
 
 class FrontendChannel;
 class DispatcherImplWeakPtr;
-using ErrorString = String;
 
 class PLATFORM_EXPORT Dispatcher {
 public:
@@ -102,15 +101,13 @@
         LastEntry,
     };
 
-    void reportProtocolError(int sessionId, int callId, CommonErrorCode, const String& errorMessage) const;
-    virtual void reportProtocolError(int sessionId, int callId, CommonErrorCode, const String& errorMessage, ErrorSupport*) const = 0;
-    virtual void dispatch(int sessionId, const String& message) = 0;
-    static bool getCommandName(const String& message, String* result);
+    void reportProtocolError(int sessionId, int callId, CommonErrorCode, const String16& errorMessage) const;
+    virtual void reportProtocolError(int sessionId, int callId, CommonErrorCode, const String16& errorMessage, ErrorSupport*) const = 0;
+    virtual void dispatch(int sessionId, const String16& message) = 0;
+    static bool getCommandName(const String16& message, String16* result);
 };
 
 } // namespace protocol
 } // namespace blink
 
-using blink::protocol::ErrorString;
-
 #endif // !defined({{class_name}}_h)
diff --git a/ErrorSupport.cpp b/ErrorSupport.cpp
index bb0b0da..0b36009 100644
--- a/ErrorSupport.cpp
+++ b/ErrorSupport.cpp
@@ -4,20 +4,20 @@
 
 #include "platform/inspector_protocol/ErrorSupport.h"
 
-#include "wtf/text/StringBuilder.h"
+#include "platform/inspector_protocol/String16.h"
 
 namespace blink {
 namespace protocol {
 
 ErrorSupport::ErrorSupport() : m_errorString(nullptr) { }
-ErrorSupport::ErrorSupport(String* errorString) : m_errorString(errorString) { }
+ErrorSupport::ErrorSupport(String16* errorString) : m_errorString(errorString) { }
 ErrorSupport::~ErrorSupport()
 {
     if (m_errorString && hasErrors())
         *m_errorString = "Internal error(s): " + errors();
 }
 
-void ErrorSupport::setName(const String& name)
+void ErrorSupport::setName(const String16& name)
 {
     ASSERT(m_path.size());
     m_path[m_path.size() - 1] = name;
@@ -25,7 +25,7 @@
 
 void ErrorSupport::push()
 {
-    m_path.append(String());
+    m_path.append(String16());
 }
 
 void ErrorSupport::pop()
@@ -33,9 +33,9 @@
     m_path.removeLast();
 }
 
-void ErrorSupport::addError(const String& error)
+void ErrorSupport::addError(const String16& error)
 {
-    StringBuilder builder;
+    String16Builder builder;
     for (size_t i = 0; i < m_path.size(); ++i) {
         if (i)
             builder.append(".");
@@ -51,9 +51,9 @@
     return m_errors.size();
 }
 
-String ErrorSupport::errors()
+String16 ErrorSupport::errors()
 {
-    StringBuilder builder;
+    String16Builder builder;
     for (size_t i = 0; i < m_errors.size(); ++i) {
         if (i)
             builder.append("; ");
diff --git a/ErrorSupport.h b/ErrorSupport.h
index 14ad8a2..98a3340 100644
--- a/ErrorSupport.h
+++ b/ErrorSupport.h
@@ -7,7 +7,7 @@
 
 #include "platform/PlatformExport.h"
 #include "platform/inspector_protocol/Collections.h"
-#include "wtf/text/WTFString.h"
+#include "platform/inspector_protocol/String16.h"
 
 namespace blink {
 namespace protocol {
@@ -15,20 +15,20 @@
 class PLATFORM_EXPORT ErrorSupport {
 public:
     ErrorSupport();
-    ErrorSupport(String* errorString);
+    ErrorSupport(String16* errorString);
     ~ErrorSupport();
 
     void push();
-    void setName(const String&);
+    void setName(const String16&);
     void pop();
-    void addError(const String&);
+    void addError(const String16&);
     bool hasErrors();
-    String errors();
+    String16 errors();
 
 private:
-    protocol::Vector<String> m_path;
-    protocol::Vector<String> m_errors;
-    String* m_errorString;
+    protocol::Vector<String16> m_path;
+    protocol::Vector<String16> m_errors;
+    String16* m_errorString;
 };
 
 } // namespace platform
diff --git a/Frontend_cpp.template b/Frontend_cpp.template
index 8f87c95..476152c 100644
--- a/Frontend_cpp.template
+++ b/Frontend_cpp.template
@@ -6,7 +6,7 @@
 
 #include "platform/inspector_protocol/{{class_name}}.h"
 
-#include "wtf/text/WTFString.h"
+#include "platform/inspector_protocol/String16.h"
 
 namespace blink {
 namespace protocol {
diff --git a/Frontend_h.template b/Frontend_h.template
index 72a99a1..79cc64b 100644
--- a/Frontend_h.template
+++ b/Frontend_h.template
@@ -14,8 +14,6 @@
 namespace blink {
 namespace protocol {
 
-using ErrorString = String;
-
 class PLATFORM_EXPORT Frontend {
 public:
     Frontend(FrontendChannel*);
diff --git a/Maybe.h b/Maybe.h
index e65b599..8116b54 100644
--- a/Maybe.h
+++ b/Maybe.h
@@ -6,11 +6,12 @@
 #define Maybe_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 namespace protocol {
 
+class String16;
+
 template<typename T>
 class Maybe {
 public:
@@ -70,7 +71,14 @@
 public:
     Maybe() { }
     Maybe(const String& value) : MaybeBase(value) { }
-    Maybe(const AtomicString& value) : MaybeBase(value) { }
+    using MaybeBase::operator=;
+};
+
+template<>
+class Maybe<String16> : public MaybeBase<String16> {
+public:
+    Maybe() { }
+    Maybe(const String16& value) : MaybeBase(value) { }
     using MaybeBase::operator=;
 };
 
diff --git a/Parser.cpp b/Parser.cpp
index ce72028..3495255 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -4,10 +4,8 @@
 
 #include "platform/inspector_protocol/Parser.h"
 
-#include "platform/Decimal.h"
+#include "platform/inspector_protocol/String16.h"
 #include "platform/inspector_protocol/Values.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/UTF8.h"
 
 namespace blink {
 namespace protocol {
@@ -299,7 +297,7 @@
 }
 
 template<typename CharType>
-bool decodeUTF8(const CharType* start, const CharType* end, const CharType** utf8charEnd, StringBuilder* output)
+bool decodeUTF8(const CharType* start, const CharType* end, const CharType** utf8charEnd, String16Builder* output)
 {
     UChar utf16[4] = {0};
     char utf8[6] = {0};
@@ -318,12 +316,12 @@
 
         const char* utf8start = utf8;
         UChar* utf16start = utf16;
-        WTF::Unicode::ConversionResult conversionResult = WTF::Unicode::convertUTF8ToUTF16(&utf8start, utf8start + utf8count, &utf16start, utf16start + WTF_ARRAY_LENGTH(utf16), nullptr, true);
+        String16::ConversionResult conversionResult = String16::convertUTF8ToUTF16(&utf8start, utf8start + utf8count, &utf16start, utf16start + 4, nullptr, true);
 
-        if (conversionResult == WTF::Unicode::sourceIllegal)
+        if (conversionResult == String16::sourceIllegal)
             return false;
 
-        if (conversionResult == WTF::Unicode::conversionOK) {
+        if (conversionResult == String16::conversionOK) {
             // Not all utf8 characters were consumed - failed parsing.
             if (utf8start != utf8 + utf8count)
                 return false;
@@ -335,7 +333,7 @@
         }
 
         // Keep accumulating utf8 characters up to buffer length (6 should be enough).
-        if (utf8count >= WTF_ARRAY_LENGTH(utf8))
+        if (utf8count >= 6)
             return false;
     }
 
@@ -343,7 +341,7 @@
 }
 
 template<typename CharType>
-bool decodeString(const CharType* start, const CharType* end, StringBuilder* output)
+bool decodeString(const CharType* start, const CharType* end, String16Builder* output)
 {
     while (start < end) {
         UChar c = *start++;
@@ -399,7 +397,7 @@
 }
 
 template<typename CharType>
-bool decodeString(const CharType* start, const CharType* end, String* output)
+bool decodeString(const CharType* start, const CharType* end, String16* output)
 {
     if (start == end) {
         *output = "";
@@ -407,13 +405,13 @@
     }
     if (start > end)
         return false;
-    StringBuilder buffer;
+    String16Builder buffer;
     buffer.reserveCapacity(end - start);
     if (!decodeString(start, end, &buffer))
         return false;
     *output = buffer.toString();
     // Validate constructed utf16 string.
-    if (output->utf8(StrictUTF8Conversion).isNull())
+    if (!output->validateUTF8())
         return false;
     return true;
 }
@@ -442,16 +440,14 @@
         break;
     case Number: {
         bool ok;
-        double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
-        if (Decimal::fromDouble(value).isInfinity())
-            ok = false;
+        double value = String16::charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
         if (!ok)
             return nullptr;
         result = FundamentalValue::create(value);
         break;
     }
     case StringLiteral: {
-        String value;
+        String16 value;
         bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
         if (!ok)
             return nullptr;
@@ -493,7 +489,7 @@
         while (token != ObjectEnd) {
             if (token != StringLiteral)
                 return nullptr;
-            String key;
+            String16 key;
             if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
                 return nullptr;
             start = tokenEnd;
@@ -550,7 +546,7 @@
 
 } // anonymous namespace
 
-PassOwnPtr<Value> parseJSON(const String& json)
+PassOwnPtr<Value> parseJSON(const String16& json)
 {
     if (json.isEmpty())
         return nullptr;
diff --git a/Parser.h b/Parser.h
index 224aaf4..49f86aa 100644
--- a/Parser.h
+++ b/Parser.h
@@ -6,14 +6,15 @@
 #define Parser_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/text/WTFString.h"
+#include "platform/inspector_protocol/String16.h"
+#include "wtf/PassOwnPtr.h"
 
 namespace blink {
 namespace protocol {
 
 class Value;
 
-PLATFORM_EXPORT PassOwnPtr<Value> parseJSON(const String& json);
+PLATFORM_EXPORT PassOwnPtr<Value> parseJSON(const String16& json);
 
 } // namespace platform
 } // namespace blink
diff --git a/ParserTest.cpp b/ParserTest.cpp
index 83420ff..6f4d5c7 100644
--- a/ParserTest.cpp
+++ b/ParserTest.cpp
@@ -4,9 +4,9 @@
 
 #include "platform/inspector_protocol/Parser.h"
 
+#include "platform/inspector_protocol/String16.h"
 #include "platform/inspector_protocol/Values.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/text/StringBuilder.h"
 
 namespace blink {
 namespace protocol {
@@ -16,7 +16,7 @@
     protocol::Value* tmpValue;
     OwnPtr<protocol::Value> root;
     OwnPtr<protocol::Value> root2;
-    String strVal;
+    String16 strVal;
     int intVal = 0;
 
     // some whitespace checking
@@ -190,10 +190,6 @@
     EXPECT_FALSE(root.get());
 
     // INF/-INF/NaN are not valid
-    root = parseJSON("1e1000");
-    EXPECT_FALSE(root.get());
-    root = parseJSON("-1e1000");
-    EXPECT_FALSE(root.get());
     root = parseJSON("NaN");
     EXPECT_FALSE(root.get());
     root = parseJSON("nan");
@@ -234,7 +230,7 @@
     EXPECT_EQ(Value::TypeString, root->type());
     EXPECT_TRUE(root->asString(&strVal));
     UChar tmp1[] = {0x41, 0, 0x1234};
-    EXPECT_EQ(String(tmp1, WTF_ARRAY_LENGTH(tmp1)), strVal);
+    EXPECT_EQ(String16(tmp1, 3), strVal);
 
     // Test invalid strings
     root = parseJSON("\"no closing quote");
@@ -428,7 +424,7 @@
     EXPECT_FALSE(root.get());
 
     // Test stack overflow
-    StringBuilder evil;
+    String16Builder evil;
     evil.reserveCapacity(2000000);
     for (int i = 0; i < 1000000; ++i)
         evil.append('[');
@@ -438,7 +434,7 @@
     EXPECT_FALSE(root.get());
 
     // A few thousand adjacent lists is fine.
-    StringBuilder notEvil;
+    String16Builder notEvil;
     notEvil.reserveCapacity(15010);
     notEvil.append('[');
     for (int i = 0; i < 5000; ++i)
@@ -457,7 +453,7 @@
     EXPECT_EQ(Value::TypeString, root->type());
     EXPECT_TRUE(root->asString(&strVal));
     UChar tmp4[] = {0x7f51, 0x9875};
-    EXPECT_EQ(String(tmp4, WTF_ARRAY_LENGTH(tmp4)), strVal);
+    EXPECT_EQ(String16(tmp4, 2), strVal);
 
     root = parseJSON("{\"path\": \"/tmp/\\xc3\\xa0\\xc3\\xa8\\xc3\\xb2.png\"}");
     ASSERT_TRUE(root.get());
@@ -466,7 +462,7 @@
     ASSERT_TRUE(objectVal);
     EXPECT_TRUE(objectVal->getString("path", &strVal));
     UChar tmp5[] = {0x2f, 0x74, 0x6d, 0x70, 0x2f, 0xe0, 0xe8, 0xf2, 0x2e, 0x70, 0x6e, 0x67};
-    EXPECT_EQ(String(tmp5, WTF_ARRAY_LENGTH(tmp5)), strVal);
+    EXPECT_EQ(String16(tmp5, 12), strVal);
 
     // Test invalid utf8 encoded input
     root = parseJSON("\"345\\xb0\\xa1\\xb0\\xa2\"");
@@ -482,14 +478,14 @@
     EXPECT_EQ(Value::TypeString, root->type());
     EXPECT_TRUE(root->asString(&strVal));
     UChar tmp2[] = {0x20ac, 0x33, 0x2c, 0x31, 0x34};
-    EXPECT_EQ(String(tmp2, WTF_ARRAY_LENGTH(tmp2)), strVal);
+    EXPECT_EQ(String16(tmp2, 5), strVal);
 
     root = parseJSON("\"\\ud83d\\udca9\\ud83d\\udc6c\"");
     ASSERT_TRUE(root.get());
     EXPECT_EQ(Value::TypeString, root->type());
     EXPECT_TRUE(root->asString(&strVal));
     UChar tmp3[] = {0xd83d, 0xdca9, 0xd83d, 0xdc6c};
-    EXPECT_EQ(String(tmp3, WTF_ARRAY_LENGTH(tmp3)), strVal);
+    EXPECT_EQ(String16(tmp3, 4), strVal);
 
     // Test invalid utf16 strings.
     const char* const cases[] = {
@@ -502,7 +498,7 @@
         "\"\\ud83foo\"", // No lower surrogate.
         "\"\\ud83\\foo\"" // No lower surrogate.
     };
-    for (size_t i = 0; i < WTF_ARRAY_LENGTH(cases); ++i) {
+    for (size_t i = 0; i < 8; ++i) {
         root = parseJSON(cases[i]);
         EXPECT_FALSE(root.get()) << cases[i];
     }
@@ -543,7 +539,7 @@
         "//**/"
     };
 
-    for (size_t i = 0; i < WTF_ARRAY_LENGTH(invalidJson); ++i) {
+    for (size_t i = 0; i < 11; ++i) {
         OwnPtr<protocol::Value> result = parseJSON(invalidJson[i]);
         EXPECT_FALSE(result.get());
     }
diff --git a/String16.h b/String16.h
new file mode 100644
index 0000000..af2f390
--- /dev/null
+++ b/String16.h
@@ -0,0 +1,10 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef String16_h
+#define String16_h
+
+#include "platform/inspector_protocol/String16WTF.h"
+
+#endif // !defined(String16_h)
diff --git a/String16WTF.h b/String16WTF.h
new file mode 100644
index 0000000..f34ebb6
--- /dev/null
+++ b/String16WTF.h
@@ -0,0 +1,175 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef String16WTF_h
+#define String16WTF_h
+
+#include "platform/Decimal.h"
+#include "public/platform/WebString.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/StringConcatenate.h"
+#include "wtf/text/StringHash.h"
+#include "wtf/text/UTF8.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+namespace protocol {
+
+class String16 {
+public:
+    String16() { }
+    String16(const String16& other) : m_impl(other.m_impl) { }
+    String16(const UChar* u, unsigned length) : m_impl(u, length) { }
+    String16(const char* characters) : m_impl(characters) { }
+    String16(const char* characters, size_t size) : m_impl(characters, size) { }
+    String16(const WebString& other) : m_impl(other) { }
+    template<typename StringType1, typename StringType2>
+    String16(const WTF::StringAppend<StringType1, StringType2>& impl) : m_impl(impl) { }
+    ~String16() { }
+
+    // Integration constructors.
+    String16(const WTF::String& impl) : m_impl(impl) { }
+    String16(const WTF::AtomicString& impl) : m_impl(impl) { }
+    String16(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { }
+
+    static String16 fromUTF8(const char* characters, size_t length) { return String::fromUTF8(characters, length); }
+    static String16 number(int i) { return String::number(i); }
+    static String16 fromDouble(double number) { return Decimal::fromDouble(number).toString(); }
+    static String16 createUninitialized(unsigned length, UChar*& data) { return String::createUninitialized(length, data); }
+    static bool codePointCompareLessThan(const String16& a, const String16& b)
+    {
+        return codePointCompare(a.impl(), b.impl()) < 0;
+    }
+
+    typedef enum {
+        conversionOK,
+        sourceExhausted,
+        targetExhausted,
+        sourceIllegal
+    } ConversionResult;
+
+    static ConversionResult convertUTF8ToUTF16(const char** sourceStart, const char* sourceEnd, UChar** targetStart, UChar* targetEnd, bool* isSourceAllASCII = 0, bool strict = true)
+    {
+        return static_cast<ConversionResult>(WTF::Unicode::convertUTF8ToUTF16(sourceStart, sourceEnd, targetStart, targetEnd, isSourceAllASCII, strict));
+    }
+
+    bool validateUTF8()
+    {
+        return !m_impl.utf8(StrictUTF8Conversion).isNull();
+    }
+
+    size_t length() const { return m_impl.length(); }
+    bool isEmpty() const { return m_impl.isEmpty(); }
+    bool isNull() const { return m_impl.isNull(); }
+    UChar operator[](unsigned index) const { return m_impl[index]; }
+
+    bool is8Bit() const { return m_impl.is8Bit(); }
+    unsigned sizeInBytes() const { return m_impl.sizeInBytes(); }
+    const LChar* characters8() const { return m_impl.characters8(); }
+    const UChar* characters16() const { return m_impl.characters16(); }
+    String16 latin1Data()
+    {
+        CString latin1 = m_impl.latin1();
+        // Include terminating zero.
+        return String16(latin1.data(), latin1.length() + 1);
+    }
+
+    operator WTF::String() const { return m_impl; }
+    operator WebString() const { return m_impl; }
+    WTF::String impl() const { return m_impl; }
+
+    static double charactersToDouble(const LChar* characters, size_t length, bool* ok = 0) { return ::charactersToDouble(characters, length, ok); }
+    static double charactersToDouble(const UChar* characters, size_t length, bool* ok = 0) { return ::charactersToDouble(characters, length, ok); }
+
+    String16 substring(unsigned pos, unsigned len = UINT_MAX) const { return m_impl.substring(pos, len); }
+    String16 left(unsigned len) const { return m_impl.substring(0, len); }
+    String16 stripWhiteSpace() const { return m_impl.stripWhiteSpace(); }
+
+    int toInt(bool* ok = 0) const { return m_impl.toInt(ok); }
+    unsigned toUInt(bool* ok = 0) const { return m_impl.toUInt(ok); }
+
+    size_t find(UChar c, unsigned start = 0) const { return m_impl.find(c, start); }
+    size_t find(const String16& str) const  { return m_impl.find(str.impl()); }
+    size_t find(const String16& str, unsigned start) const { return m_impl.find(str.impl(), start); }
+    size_t reverseFind(const String16& str, unsigned start = UINT_MAX) const { return m_impl.reverseFind(str.impl(), start); }
+
+    void append(const String16& str) { m_impl.append(str); };
+    bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); }
+
+    bool startWith(const String16& s) const { return m_impl.startsWith(s); }
+    bool startWith(UChar character) const { return m_impl.startsWith(character); }
+    bool endsWith(const String16& s) const { return m_impl.endsWith(s); }
+    bool endsWith(UChar character) const { return m_impl.endsWith(character); }
+
+private:
+    WTF::String m_impl;
+};
+
+class String16Builder {
+public:
+    String16Builder() { }
+    void append(const String16& str) { m_impl.append(str); };
+    void append(UChar c) { m_impl.append(c); };
+    void append(LChar c) { m_impl.append(c); };
+    void append(char c) { m_impl.append(c); };
+    void append(const UChar* c, size_t size) { m_impl.append(c, size); };
+    void append(const char* characters, unsigned length) { m_impl.append(characters, length); }
+    void appendNumber(int number) { m_impl.appendNumber(number); }
+    String16 toString() { return m_impl.toString(); }
+    void reserveCapacity(unsigned newCapacity) { m_impl.reserveCapacity(newCapacity); }
+
+private:
+    WTF::StringBuilder m_impl;
+};
+
+inline bool operator==(const String16& a, const String16& b) { return a.impl() == b.impl(); }
+inline bool operator!=(const String16& a, const String16& b) { return a.impl() != b.impl(); }
+inline bool operator==(const String16& a, const char* b) { return a.impl() == b; }
+
+inline String16 operator+(const String16& a, const char* b)
+{
+    return String(a.impl() + b);
+}
+
+inline String16 operator+(const char* a, const String16& b)
+{
+    return String(a + b.impl());
+}
+
+inline String16 operator+(const String16& a, const String16& b)
+{
+    return String(a.impl() + b.impl());
+}
+
+} // namespace protocol
+} // namespace blink
+
+using String16 = blink::protocol::String16;
+using String16Builder = blink::protocol::String16Builder;
+
+namespace WTF {
+
+struct String16Hash {
+    static unsigned hash(const String16& key) { return StringHash::hash(key.impl()); }
+    static bool equal(const String16& a, const String16& b)
+    {
+        return StringHash::equal(a.impl(), b.impl());
+    }
+    static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<String16> {
+    typedef String16Hash Hash;
+};
+
+template<>
+struct HashTraits<String16> : SimpleClassHashTraits<String16> {
+    static const bool hasIsEmptyValueFunction = true;
+    static bool isEmptyValue(const String16& a) { return a.isNull(); }
+};
+
+} // namespace WTF
+
+#endif // !defined(String16WTF_h)
diff --git a/TypeBuilder_h.template b/TypeBuilder_h.template
index d81e08c..ea3a579 100644
--- a/TypeBuilder_h.template
+++ b/TypeBuilder_h.template
@@ -11,16 +11,17 @@
 #include "platform/inspector_protocol/Array.h"
 #include "platform/inspector_protocol/ErrorSupport.h"
 #include "platform/inspector_protocol/Maybe.h"
+#include "platform/inspector_protocol/String16.h"
 #include "platform/inspector_protocol/Values.h"
 #include "platform/inspector_protocol/ValueConversions.h"
 #include "wtf/Assertions.h"
 #include "wtf/PassOwnPtr.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 namespace protocol {
 
+using ErrorString = String16;
+
 class PLATFORM_EXPORT Object {
 public:
     static PassOwnPtr<Object> parse(protocol::Value* value, ErrorSupport* errors);
@@ -205,4 +206,6 @@
 } // namespace protocol
 } // namespace blink
 
+using blink::protocol::ErrorString;
+
 #endif // !defined({{class_name}}_h)
diff --git a/ValueConversions.cpp b/ValueConversions.cpp
index 2d03512..3e61c6c 100644
--- a/ValueConversions.cpp
+++ b/ValueConversions.cpp
@@ -22,6 +22,11 @@
     return FundamentalValue::create(value);
 }
 
+PassOwnPtr<protocol::Value> toValue(const String16& param)
+{
+    return StringValue::create(param);
+}
+
 PassOwnPtr<protocol::Value> toValue(const String& param)
 {
     return StringValue::create(param);
diff --git a/ValueConversions.h b/ValueConversions.h
index ea2c393..e8df222 100644
--- a/ValueConversions.h
+++ b/ValueConversions.h
@@ -7,8 +7,8 @@
 
 #include "platform/PlatformExport.h"
 #include "platform/inspector_protocol/ErrorSupport.h"
+#include "platform/inspector_protocol/String16.h"
 #include "platform/inspector_protocol/Values.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 namespace protocol {
@@ -19,6 +19,8 @@
 
 PLATFORM_EXPORT PassOwnPtr<protocol::Value> toValue(bool value);
 
+PLATFORM_EXPORT PassOwnPtr<protocol::Value> toValue(const String16& param);
+
 PLATFORM_EXPORT PassOwnPtr<protocol::Value> toValue(const String& param);
 
 PLATFORM_EXPORT PassOwnPtr<protocol::Value> toValue(protocol::Value* param);
@@ -92,7 +94,19 @@
 struct FromValue<String> {
     static String parse(protocol::Value* value, ErrorSupport* errors)
     {
-        String result;
+        String16 result;
+        bool success = value ? value->asString(&result) : false;
+        if (!success)
+            errors->addError("string value expected");
+        return result;
+    }
+};
+
+template<>
+struct FromValue<String16> {
+    static String16 parse(protocol::Value* value, ErrorSupport* errors)
+    {
+        String16 result;
         bool success = value ? value->asString(&result) : false;
         if (!success)
             errors->addError("string value expected");
@@ -104,7 +118,6 @@
 struct FromValue<Value> {
     static PassOwnPtr<Value> parse(protocol::Value* value, ErrorSupport* errors)
     {
-        String result;
         bool success = !!value;
         if (!success)
             errors->addError("value expected");
@@ -116,7 +129,6 @@
 struct FromValue<DictionaryValue> {
     static PassOwnPtr<DictionaryValue> parse(protocol::Value* value, ErrorSupport* errors)
     {
-        String result;
         bool success = value && value->type() == protocol::Value::TypeObject;
         if (!success)
             errors->addError("object expected");
@@ -128,7 +140,6 @@
 struct FromValue<ListValue> {
     static PassOwnPtr<ListValue> parse(protocol::Value* value, ErrorSupport* errors)
     {
-        String result;
         bool success = value && value->type() == protocol::Value::TypeArray;
         if (!success)
             errors->addError("list expected");
diff --git a/Values.cpp b/Values.cpp
index 4f7a6a4..03569db 100644
--- a/Values.cpp
+++ b/Values.cpp
@@ -4,9 +4,8 @@
 
 #include "platform/inspector_protocol/Values.h"
 
-#include "platform/Decimal.h"
 #include "platform/inspector_protocol/Parser.h"
-#include "wtf/text/StringBuilder.h"
+#include "platform/inspector_protocol/String16.h"
 #include <cmath>
 
 namespace blink {
@@ -18,23 +17,34 @@
 const char* const trueString = "true";
 const char* const falseString = "false";
 
-inline bool escapeChar(UChar c, StringBuilder* dst)
+inline bool escapeChar(UChar c, String16Builder* dst)
 {
     switch (c) {
-    case '\b': dst->appendLiteral("\\b"); break;
-    case '\f': dst->appendLiteral("\\f"); break;
-    case '\n': dst->appendLiteral("\\n"); break;
-    case '\r': dst->appendLiteral("\\r"); break;
-    case '\t': dst->appendLiteral("\\t"); break;
-    case '\\': dst->appendLiteral("\\\\"); break;
-    case '"': dst->appendLiteral("\\\""); break;
+    case '\b': dst->append("\\b"); break;
+    case '\f': dst->append("\\f"); break;
+    case '\n': dst->append("\\n"); break;
+    case '\r': dst->append("\\r"); break;
+    case '\t': dst->append("\\t"); break;
+    case '\\': dst->append("\\\\"); break;
+    case '"': dst->append("\\\""); break;
     default:
         return false;
     }
     return true;
 }
 
-void escapeStringForJSON(const String& str, StringBuilder* dst)
+const LChar hexDigits[17] = "0123456789ABCDEF";
+
+void appendUnsignedAsHex(UChar number, String16Builder* dst)
+{
+    dst->append("\\u");
+    for (size_t i = 0; i < 4; ++i) {
+        dst->append(hexDigits[(number & 0xF000) >> 12]);
+        number <<= 4;
+    }
+}
+
+void escapeStringForJSON(const String16& str, String16Builder* dst)
 {
     for (unsigned i = 0; i < str.length(); ++i) {
         UChar c = str[i];
@@ -43,9 +53,7 @@
                 // 1. Escaping <, > to prevent script execution.
                 // 2. Technically, we could also pass through c > 126 as UTF8, but this
                 //    is also optional. It would also be a pain to implement here.
-                unsigned symbol = static_cast<unsigned>(c);
-                String symbolCode = String::format("\\u%04X", symbol);
-                dst->append(symbolCode);
+                appendUnsignedAsHex(c, dst);
             } else {
                 dst->append(c);
             }
@@ -53,7 +61,7 @@
     }
 }
 
-void doubleQuoteStringForJSON(const String& str, StringBuilder* dst)
+void doubleQuoteStringForJSON(const String16& str, String16Builder* dst)
 {
     dst->append('"');
     escapeStringForJSON(str, dst);
@@ -77,20 +85,20 @@
     return false;
 }
 
-bool Value::asString(String*) const
+bool Value::asString(String16*) const
 {
     return false;
 }
 
-String Value::toJSONString() const
+String16 Value::toJSONString() const
 {
-    StringBuilder result;
+    String16Builder result;
     result.reserveCapacity(512);
     writeJSON(&result);
     return result.toString();
 }
 
-void Value::writeJSON(StringBuilder* output) const
+void Value::writeJSON(String16Builder* output) const
 {
     ASSERT(m_type == TypeNull);
     output->append(nullString, 4);
@@ -125,7 +133,7 @@
     return true;
 }
 
-void FundamentalValue::writeJSON(StringBuilder* output) const
+void FundamentalValue::writeJSON(String16Builder* output) const
 {
     ASSERT(type() == TypeBoolean || type() == TypeNumber);
     if (type() == TypeBoolean) {
@@ -138,7 +146,7 @@
             output->append(nullString, 4);
             return;
         }
-        output->append(Decimal::fromDouble(m_doubleValue).toString());
+        output->append(String16::fromDouble(m_doubleValue));
     }
 }
 
@@ -147,13 +155,13 @@
     return type() == TypeNumber ? FundamentalValue::create(m_doubleValue) : FundamentalValue::create(m_boolValue);
 }
 
-bool StringValue::asString(String* output) const
+bool StringValue::asString(String16* output) const
 {
     *output = m_stringValue;
     return true;
 }
 
-void StringValue::writeJSON(StringBuilder* output) const
+void StringValue::writeJSON(String16Builder* output) const
 {
     ASSERT(type() == TypeString);
     doubleQuoteStringForJSON(m_stringValue, output);
@@ -168,43 +176,43 @@
 {
 }
 
-void DictionaryValue::setBoolean(const String& name, bool value)
+void DictionaryValue::setBoolean(const String16& name, bool value)
 {
     setValue(name, FundamentalValue::create(value));
 }
 
-void DictionaryValue::setNumber(const String& name, double value)
+void DictionaryValue::setNumber(const String16& name, double value)
 {
     setValue(name, FundamentalValue::create(value));
 }
 
-void DictionaryValue::setString(const String& name, const String& value)
+void DictionaryValue::setString(const String16& name, const String16& value)
 {
     setValue(name, StringValue::create(value));
 }
 
-void DictionaryValue::setValue(const String& name, PassOwnPtr<Value> value)
+void DictionaryValue::setValue(const String16& name, PassOwnPtr<Value> value)
 {
     ASSERT(value);
     if (m_data.set(name, value))
         m_order.append(name);
 }
 
-void DictionaryValue::setObject(const String& name, PassOwnPtr<DictionaryValue> value)
+void DictionaryValue::setObject(const String16& name, PassOwnPtr<DictionaryValue> value)
 {
     ASSERT(value);
     if (m_data.set(name, value))
         m_order.append(name);
 }
 
-void DictionaryValue::setArray(const String& name, PassOwnPtr<ListValue> value)
+void DictionaryValue::setArray(const String16& name, PassOwnPtr<ListValue> value)
 {
     ASSERT(value);
     if (m_data.set(name, value))
         m_order.append(name);
 }
 
-bool DictionaryValue::getBoolean(const String& name, bool* output) const
+bool DictionaryValue::getBoolean(const String16& name, bool* output) const
 {
     protocol::Value* value = get(name);
     if (!value)
@@ -212,7 +220,7 @@
     return value->asBoolean(output);
 }
 
-bool DictionaryValue::getString(const String& name, String* output) const
+bool DictionaryValue::getString(const String16& name, String16* output) const
 {
     protocol::Value* value = get(name);
     if (!value)
@@ -220,17 +228,17 @@
     return value->asString(output);
 }
 
-DictionaryValue* DictionaryValue::getObject(const String& name) const
+DictionaryValue* DictionaryValue::getObject(const String16& name) const
 {
     return DictionaryValue::cast(get(name));
 }
 
-protocol::ListValue* DictionaryValue::getArray(const String& name) const
+protocol::ListValue* DictionaryValue::getArray(const String16& name) const
 {
     return ListValue::cast(get(name));
 }
 
-protocol::Value* DictionaryValue::get(const String& name) const
+protocol::Value* DictionaryValue::get(const String16& name) const
 {
     Dictionary::const_iterator it = m_data.find(name);
     if (it == m_data.end())
@@ -240,18 +248,18 @@
 
 DictionaryValue::Entry DictionaryValue::at(size_t index) const
 {
-    String key = m_order[index];
+    String16 key = m_order[index];
     return std::make_pair(key, m_data.get(key));
 }
 
-bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
+bool DictionaryValue::booleanProperty(const String16& name, bool defaultValue) const
 {
     bool result = defaultValue;
     getBoolean(name, &result);
     return result;
 }
 
-void DictionaryValue::remove(const String& name)
+void DictionaryValue::remove(const String16& name)
 {
     m_data.remove(name);
     for (size_t i = 0; i < m_order.size(); ++i) {
@@ -262,7 +270,7 @@
     }
 }
 
-void DictionaryValue::writeJSON(StringBuilder* output) const
+void DictionaryValue::writeJSON(String16Builder* output) const
 {
     output->append('{');
     for (size_t i = 0; i < m_order.size(); ++i) {
@@ -281,7 +289,7 @@
 {
     OwnPtr<DictionaryValue> result = DictionaryValue::create();
     for (size_t i = 0; i < m_order.size(); ++i) {
-        String key = m_order[i];
+        String16 key = m_order[i];
         Value* value = m_data.get(key);
         ASSERT(value);
         result->setValue(key, value->clone());
@@ -298,7 +306,7 @@
 {
 }
 
-void ListValue::writeJSON(StringBuilder* output) const
+void ListValue::writeJSON(String16Builder* output) const
 {
     output->append('[');
     for (Vector<OwnPtr<protocol::Value>>::const_iterator it = m_data.begin(); it != m_data.end(); ++it) {
diff --git a/Values.h b/Values.h
index 8944e9f..f136662 100644
--- a/Values.h
+++ b/Values.h
@@ -8,9 +8,8 @@
 #include "platform/PlatformExport.h"
 #include "platform/inspector_protocol/Allocator.h"
 #include "platform/inspector_protocol/Collections.h"
+#include "platform/inspector_protocol/String16.h"
 #include "wtf/PassOwnPtr.h"
-#include "wtf/text/StringHash.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 namespace protocol {
@@ -47,10 +46,10 @@
     virtual bool asBoolean(bool* output) const;
     virtual bool asNumber(double* output) const;
     virtual bool asNumber(int* output) const;
-    virtual bool asString(String* output) const;
+    virtual bool asString(String16* output) const;
 
-    String toJSONString() const;
-    virtual void writeJSON(StringBuilder* output) const;
+    String16 toJSONString() const;
+    virtual void writeJSON(String16Builder* output) const;
     virtual PassOwnPtr<Value> clone() const;
 
 protected:
@@ -84,7 +83,7 @@
     bool asBoolean(bool* output) const override;
     bool asNumber(double* output) const override;
     bool asNumber(int* output) const override;
-    void writeJSON(StringBuilder* output) const override;
+    void writeJSON(String16Builder* output) const override;
     PassOwnPtr<Value> clone() const override;
 
 private:
@@ -100,7 +99,7 @@
 
 class PLATFORM_EXPORT StringValue : public Value {
 public:
-    static PassOwnPtr<StringValue> create(const String& value)
+    static PassOwnPtr<StringValue> create(const String16& value)
     {
         return adoptPtr(new StringValue(value));
     }
@@ -110,20 +109,20 @@
         return adoptPtr(new StringValue(value));
     }
 
-    bool asString(String* output) const override;
-    void writeJSON(StringBuilder* output) const override;
+    bool asString(String16* output) const override;
+    void writeJSON(String16Builder* output) const override;
     PassOwnPtr<Value> clone() const override;
 
 private:
-    explicit StringValue(const String& value) : Value(TypeString), m_stringValue(value) { }
+    explicit StringValue(const String16& value) : Value(TypeString), m_stringValue(value) { }
     explicit StringValue(const char* value) : Value(TypeString), m_stringValue(value) { }
 
-    String m_stringValue;
+    String16 m_stringValue;
 };
 
 class PLATFORM_EXPORT DictionaryValue : public Value {
 public:
-    using Entry = std::pair<String, Value*>;
+    using Entry = std::pair<String16, Value*>;
     static PassOwnPtr<DictionaryValue> create()
     {
         return adoptPtr(new DictionaryValue());
@@ -141,44 +140,44 @@
         return adoptPtr(DictionaryValue::cast(value.leakPtr()));
     }
 
-    void writeJSON(StringBuilder* output) const override;
+    void writeJSON(String16Builder* output) const override;
     PassOwnPtr<Value> clone() const override;
 
     size_t size() const { return m_data.size(); }
 
-    void setBoolean(const String& name, bool);
-    void setNumber(const String& name, double);
-    void setString(const String& name, const String&);
-    void setValue(const String& name, PassOwnPtr<Value>);
-    void setObject(const String& name, PassOwnPtr<DictionaryValue>);
-    void setArray(const String& name, PassOwnPtr<ListValue>);
+    void setBoolean(const String16& name, bool);
+    void setNumber(const String16& name, double);
+    void setString(const String16& name, const String16&);
+    void setValue(const String16& name, PassOwnPtr<Value>);
+    void setObject(const String16& name, PassOwnPtr<DictionaryValue>);
+    void setArray(const String16& name, PassOwnPtr<ListValue>);
 
-    bool getBoolean(const String& name, bool* output) const;
-    template<class T> bool getNumber(const String& name, T* output) const
+    bool getBoolean(const String16& name, bool* output) const;
+    template<class T> bool getNumber(const String16& name, T* output) const
     {
         Value* value = get(name);
         if (!value)
             return false;
         return value->asNumber(output);
     }
-    bool getString(const String& name, String* output) const;
+    bool getString(const String16& name, String16* output) const;
 
-    DictionaryValue* getObject(const String& name) const;
-    ListValue* getArray(const String& name) const;
-    Value* get(const String& name) const;
+    DictionaryValue* getObject(const String16& name) const;
+    ListValue* getArray(const String16& name) const;
+    Value* get(const String16& name) const;
     Entry at(size_t index) const;
 
-    bool booleanProperty(const String& name, bool defaultValue) const;
-    void remove(const String& name);
+    bool booleanProperty(const String16& name, bool defaultValue) const;
+    void remove(const String16& name);
 
     ~DictionaryValue() override;
 
 private:
     DictionaryValue();
 
-    using Dictionary = protocol::HashMap<String, OwnPtr<Value>>;
+    using Dictionary = protocol::HashMap<String16, OwnPtr<Value>>;
     Dictionary m_data;
-    protocol::Vector<String> m_order;
+    protocol::Vector<String16> m_order;
 };
 
 class PLATFORM_EXPORT ListValue : public Value {
@@ -202,7 +201,7 @@
 
     ~ListValue() override;
 
-    void writeJSON(StringBuilder* output) const override;
+    void writeJSON(String16Builder* output) const override;
     PassOwnPtr<Value> clone() const override;
 
     void pushValue(PassOwnPtr<Value>);
diff --git a/generate-inspector-protocol-version b/generate-inspector-protocol-version
index 2054e1e..4abe511 100755
--- a/generate-inspector-protocol-version
+++ b/generate-inspector-protocol-version
@@ -435,7 +435,7 @@
 #ifndef InspectorProtocolVersion_h
 #define InspectorProtocolVersion_h
 
-#include "wtf/text/WTFString.h"
+#include "platform/inspector_protocol/String16.h"
 
 namespace blink {